Skip to content

Commit e84d5e9

Browse files
committed
Merge branch 'ew/force-ipv4'
"git fetch" and friends that make network connections can now be told to only use ipv4 (or ipv6). * ew/force-ipv4: connect & http: support -4 and -6 switches for remote operations
2 parents 8020803 + c915f11 commit e84d5e9

File tree

13 files changed

+95
-0
lines changed

13 files changed

+95
-0
lines changed

Documentation/fetch-options.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,11 @@ endif::git-pull[]
158158
by default when it is attached to a terminal, unless -q
159159
is specified. This flag forces progress status even if the
160160
standard error stream is not directed to a terminal.
161+
162+
-4::
163+
--ipv4::
164+
Use IPv4 addresses only, ignoring IPv6 addresses.
165+
166+
-6::
167+
--ipv6::
168+
Use IPv6 addresses only, ignoring IPv4 addresses.

Documentation/git-push.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,13 @@ origin +master` to force a push to the `master` branch). See the
277277
default is --verify, giving the hook a chance to prevent the
278278
push. With --no-verify, the hook is bypassed completely.
279279

280+
-4::
281+
--ipv4::
282+
Use IPv4 addresses only, ignoring IPv6 addresses.
283+
284+
-6::
285+
--ipv6::
286+
Use IPv6 addresses only, ignoring IPv4 addresses.
280287

281288
include::urls-remotes.txt[]
282289

builtin/clone.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ static const char *real_git_dir;
4747
static char *option_upload_pack = "git-upload-pack";
4848
static int option_verbosity;
4949
static int option_progress = -1;
50+
static enum transport_family family;
5051
static struct string_list option_config;
5152
static struct string_list option_reference;
5253
static int option_dissociate;
@@ -92,6 +93,10 @@ static struct option builtin_clone_options[] = {
9293
N_("separate git dir from working tree")),
9394
OPT_STRING_LIST('c', "config", &option_config, N_("key=value"),
9495
N_("set config inside the new repository")),
96+
OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
97+
TRANSPORT_FAMILY_IPV4),
98+
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
99+
TRANSPORT_FAMILY_IPV6),
95100
OPT_END()
96101
};
97102

@@ -970,6 +975,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
970975
remote = remote_get(option_origin);
971976
transport = transport_get(remote, remote->url[0]);
972977
transport_set_verbosity(transport, option_verbosity, option_progress);
978+
transport->family = family;
973979

974980
path = get_repo_path(remote->url[0], &is_bundle);
975981
is_local = option_local != 0 && path && !is_bundle;

builtin/fetch.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static int all, append, dry_run, force, keep, multiple, update_head_ok, verbosit
3838
static int progress = -1, recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
3939
static int tags = TAGS_DEFAULT, unshallow, update_shallow;
4040
static int max_children = 1;
41+
static enum transport_family family;
4142
static const char *depth;
4243
static const char *upload_pack;
4344
static struct strbuf default_rla = STRBUF_INIT;
@@ -127,6 +128,10 @@ static struct option builtin_fetch_options[] = {
127128
N_("accept refs that update .git/shallow")),
128129
{ OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),
129130
N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg },
131+
OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
132+
TRANSPORT_FAMILY_IPV4),
133+
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
134+
TRANSPORT_FAMILY_IPV6),
130135
OPT_END()
131136
};
132137

@@ -864,6 +869,7 @@ static struct transport *prepare_transport(struct remote *remote)
864869
struct transport *transport;
865870
transport = transport_get(remote, NULL);
866871
transport_set_verbosity(transport, verbosity, progress);
872+
transport->family = family;
867873
if (upload_pack)
868874
set_option(transport, TRANS_OPT_UPLOADPACK, upload_pack);
869875
if (keep)

builtin/push.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const char *receivepack;
2323
static int verbosity;
2424
static int progress = -1;
2525
static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
26+
static enum transport_family family;
2627

2728
static struct push_cas_option cas;
2829

@@ -346,6 +347,7 @@ static int push_with_options(struct transport *transport, int flags)
346347
unsigned int reject_reasons;
347348

348349
transport_set_verbosity(transport, verbosity, progress);
350+
transport->family = family;
349351

350352
if (receivepack)
351353
transport_set_option(transport,
@@ -565,6 +567,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
565567
0, "signed", &push_cert, "yes|no|if-asked", N_("GPG sign the push"),
566568
PARSE_OPT_OPTARG, option_parse_push_signed },
567569
OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
570+
OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
571+
TRANSPORT_FAMILY_IPV4),
572+
OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
573+
TRANSPORT_FAMILY_IPV6),
568574
OPT_END()
569575
};
570576

connect.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,10 @@ static int git_tcp_connect_sock(char *host, int flags)
357357
port = "<none>";
358358

359359
memset(&hints, 0, sizeof(hints));
360+
if (flags & CONNECT_IPV4)
361+
hints.ai_family = AF_INET;
362+
else if (flags & CONNECT_IPV6)
363+
hints.ai_family = AF_INET6;
360364
hints.ai_socktype = SOCK_STREAM;
361365
hints.ai_protocol = IPPROTO_TCP;
362366

@@ -783,6 +787,10 @@ struct child_process *git_connect(int fd[2], const char *url,
783787
}
784788

785789
argv_array_push(&conn->args, ssh);
790+
if (flags & CONNECT_IPV4)
791+
argv_array_push(&conn->args, "-4");
792+
else if (flags & CONNECT_IPV6)
793+
argv_array_push(&conn->args, "-6");
786794
if (tortoiseplink)
787795
argv_array_push(&conn->args, "-batch");
788796
if (port) {

connect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#define CONNECT_VERBOSE (1u << 0)
55
#define CONNECT_DIAG_URL (1u << 1)
6+
#define CONNECT_IPV4 (1u << 2)
7+
#define CONNECT_IPV6 (1u << 3)
68
extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
79
extern int finish_connect(struct child_process *conn);
810
extern int git_connection_is_socket(struct child_process *conn);

http.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111
#include "gettext.h"
1212
#include "transport.h"
1313

14+
#if LIBCURL_VERSION_NUM >= 0x070a08
15+
long int git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
16+
#else
17+
long int git_curl_ipresolve;
18+
#endif
1419
int active_requests;
1520
int http_is_verbose;
1621
size_t http_post_buffer = 16 * LARGE_PACKET_MAX;
@@ -824,6 +829,10 @@ struct active_request_slot *get_active_slot(void)
824829
curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1);
825830
curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1);
826831
curl_easy_setopt(slot->curl, CURLOPT_RANGE, NULL);
832+
833+
#if LIBCURL_VERSION_NUM >= 0x070a08
834+
curl_easy_setopt(slot->curl, CURLOPT_IPRESOLVE, git_curl_ipresolve);
835+
#endif
827836
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
828837
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
829838
#endif

http.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ extern void http_init(struct remote *remote, const char *url,
107107
int proactive_auth);
108108
extern void http_cleanup(void);
109109

110+
extern long int git_curl_ipresolve;
110111
extern int active_requests;
111112
extern int http_is_verbose;
112113
extern size_t http_post_buffer;

remote-curl.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,19 @@ static int set_option(const char *name, const char *value)
119119
else
120120
return -1;
121121
return 0;
122+
123+
#if LIBCURL_VERSION_NUM >= 0x070a08
124+
} else if (!strcmp(name, "family")) {
125+
if (!strcmp(value, "ipv4"))
126+
git_curl_ipresolve = CURL_IPRESOLVE_V4;
127+
else if (!strcmp(value, "ipv6"))
128+
git_curl_ipresolve = CURL_IPRESOLVE_V6;
129+
else if (!strcmp(value, "all"))
130+
git_curl_ipresolve = CURL_IPRESOLVE_WHATEVER;
131+
else
132+
return -1;
133+
return 0;
134+
#endif /* LIBCURL_VERSION_NUM >= 0x070a08 */
122135
} else {
123136
return 1 /* unsupported */;
124137
}

0 commit comments

Comments
 (0)