{"thread":{"id":"1316","subject":"[PATCH] GIT: Try all addresses for given remote name","startedAt":"2005-07-23T05:36:13Z","lastAt":"2005-07-23T05:36:13Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"6368","messageId":"7v4qam5bjm.fsf@assigned-by-dhcp.cox.net","threadId":"1316","inReplyTo":null,"subject":"[PATCH] GIT: Try all addresses for given remote name","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-23T05:36:13Z","receivedAt":"2005-07-23T05:36:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"From: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>\nDate: 1121951436 -0400\n\nTry all addresses for given remote name until it succeeds.\nAlso supports IPv6.\n\nSigned-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n*** Linus, I am not ACKing Hideaki's other change on the\n*** daemon.c side at this moment; Pasky raised two good points\n*** and I expect Hideaki will resubmit (either modified or as\n*** is).\n\n connect.c |   71 +++++++++++++++++++++++++++++++++++++------------------------\n 1 files changed, 43 insertions(+), 28 deletions(-)\n\n42210dd815647c3d4b71142a8a43de5a009485b2\ndiff --git a/connect.c b/connect.c\n--- a/connect.c\n+++ b/connect.c\n@@ -96,42 +96,57 @@ static enum protocol get_protocol(const \n \tdie(\"I don't handle protocol '%s'\", name);\n }\n \n-static void lookup_host(const char *host, struct sockaddr *in)\n-{\n-\tstruct addrinfo *res;\n-\tint ret;\n-\n-\tret = getaddrinfo(host, NULL, NULL, &res);\n-\tif (ret)\n-\t\tdie(\"Unable to look up %s (%s)\", host, gai_strerror(ret));\n-\t*in = *res->ai_addr;\n-\tfreeaddrinfo(res);\n-}\n+#define STR_(s)\t# s\n+#define STR(s)\tSTR_(s)\n \n static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)\n {\n-\tstruct sockaddr addr;\n-\tint port = DEFAULT_GIT_PORT, sockfd;\n-\tchar *colon;\n-\n-\tcolon = strchr(host, ':');\n-\tif (colon) {\n-\t\tchar *end;\n-\t\tunsigned long n = strtoul(colon+1, &end, 0);\n-\t\tif (colon[1] && !*end) {\n-\t\t\t*colon = 0;\n-\t\t\tport = n;\n+\tint sockfd = -1;\n+\tchar *colon, *end;\n+\tchar *port = STR(DEFAULT_GIT_PORT);\n+\tstruct addrinfo hints, *ai0, *ai;\n+\tint gai;\n+\n+\tif (host[0] == '[') {\n+\t\tend = strchr(host + 1, ']');\n+\t\tif (end) {\n+\t\t\t*end = 0;\n+\t\t\tend++;\n+\t\t\thost++;\n+\t\t} else\n+\t\t\tend = host;\n+\t} else\n+\t\tend = host;\n+\tcolon = strchr(end, ':');\n+\n+\tif (colon)\n+\t\tport = colon + 1;\n+\n+\tmemset(&hints, 0, sizeof(hints));\n+\thints.ai_socktype = SOCK_STREAM;\n+\thints.ai_protocol = IPPROTO_TCP;\n+\n+\tgai = getaddrinfo(host, port, &hints, &ai);\n+\tif (gai)\n+\t\tdie(\"Unable to look up %s (%s)\", host, gai_strerror(gai));\n+\n+\tfor (ai0 = ai; ai; ai = ai->ai_next) {\n+\t\tsockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);\n+\t\tif (sockfd < 0)\n+\t\t\tcontinue;\n+\t\tif (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {\n+\t\t\tclose(sockfd);\n+\t\t\tsockfd = -1;\n+\t\t\tcontinue;\n \t\t}\n+\t\tbreak;\n \t}\n \n-\tlookup_host(host, &addr);\n-\t((struct sockaddr_in *)&addr)->sin_port = htons(port);\n+\tfreeaddrinfo(ai0);\n \n-\tsockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);\n \tif (sockfd < 0)\n-\t\tdie(\"unable to create socket (%s)\", strerror(errno));\n-\tif (connect(sockfd, (void *)&addr, sizeof(addr)) < 0)\n-\t\tdie(\"unable to connect (%s)\", strerror(errno));\n+\t\tdie(\"unable to connect a socket (%s)\", strerror(errno));\n+\n \tfd[0] = sockfd;\n \tfd[1] = sockfd;\n \tpacket_write(sockfd, \"%s %s\\n\", prog, path);\n"}]}