Fossil SCM
Enhance the "fossil sync" command to retry all of the returned values from getaddrinfo() until it finds one that actually works. That way, it will find the IPv4 version on machines that do not have an IPv6 gateway.
Commit
ae3ef4d3d9d786c79afb805ad9892cca82bde046
Parent
317bd3cb3dbc5c1…
1 file changed
+18
-16
+18
-16
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -137,10 +137,11 @@ | ||
| 137 | 137 | ** Return the number of errors. |
| 138 | 138 | */ |
| 139 | 139 | int socket_open(UrlData *pUrlData){ |
| 140 | 140 | int rc = 0; |
| 141 | 141 | struct addrinfo *ai = 0; |
| 142 | + struct addrinfo *p; | |
| 142 | 143 | struct addrinfo hints; |
| 143 | 144 | char zPort[30]; |
| 144 | 145 | char zRemote[NI_MAXHOST]; |
| 145 | 146 | |
| 146 | 147 | socket_global_init(); |
| @@ -153,28 +154,29 @@ | ||
| 153 | 154 | rc = getaddrinfo(pUrlData->name, zPort, &hints, &ai); |
| 154 | 155 | if( rc ){ |
| 155 | 156 | socket_set_errmsg("getaddrinfo() fails: %s", gai_strerror(rc)); |
| 156 | 157 | goto end_socket_open; |
| 157 | 158 | } |
| 158 | - rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, sizeof(zRemote), | |
| 159 | - 0, 0, NI_NUMERICHOST); | |
| 160 | - if( rc ){ | |
| 161 | - socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); | |
| 162 | - goto end_socket_open; | |
| 163 | - } | |
| 164 | - g.zIpAddr = mprintf("%s", zRemote); | |
| 165 | - iSocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | |
| 166 | - if( iSocket<0 ){ | |
| 167 | - socket_set_errmsg("cannot create a socket"); | |
| 168 | - rc = 1; | |
| 169 | - goto end_socket_open; | |
| 170 | - } | |
| 171 | - if( connect(iSocket,ai->ai_addr,ai->ai_addrlen)<0 ){ | |
| 159 | + for(p=ai; p; p=p->ai_next){ | |
| 160 | + iSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); | |
| 161 | + if( iSocket<0 ) continue; | |
| 162 | + if( connect(iSocket,p->ai_addr,p->ai_addrlen)<0 ){ | |
| 163 | + socket_close(); | |
| 164 | + continue; | |
| 165 | + } | |
| 166 | + rc = getnameinfo(p->ai_addr, p->ai_addrlen, zRemote, sizeof(zRemote), | |
| 167 | + 0, 0, NI_NUMERICHOST); | |
| 168 | + if( rc ){ | |
| 169 | + socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); | |
| 170 | + goto end_socket_open; | |
| 171 | + } | |
| 172 | + g.zIpAddr = mprintf("%s", zRemote); | |
| 173 | + break; | |
| 174 | + } | |
| 175 | + if( p==0 ){ | |
| 172 | 176 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 173 | 177 | pUrlData->port); |
| 174 | - rc = 1; | |
| 175 | - goto end_socket_open; | |
| 176 | 178 | } |
| 177 | 179 | #if !defined(_WIN32) |
| 178 | 180 | signal(SIGPIPE, SIG_IGN); |
| 179 | 181 | #endif |
| 180 | 182 | end_socket_open: |
| 181 | 183 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -137,10 +137,11 @@ | |
| 137 | ** Return the number of errors. |
| 138 | */ |
| 139 | int socket_open(UrlData *pUrlData){ |
| 140 | int rc = 0; |
| 141 | struct addrinfo *ai = 0; |
| 142 | struct addrinfo hints; |
| 143 | char zPort[30]; |
| 144 | char zRemote[NI_MAXHOST]; |
| 145 | |
| 146 | socket_global_init(); |
| @@ -153,28 +154,29 @@ | |
| 153 | rc = getaddrinfo(pUrlData->name, zPort, &hints, &ai); |
| 154 | if( rc ){ |
| 155 | socket_set_errmsg("getaddrinfo() fails: %s", gai_strerror(rc)); |
| 156 | goto end_socket_open; |
| 157 | } |
| 158 | rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, sizeof(zRemote), |
| 159 | 0, 0, NI_NUMERICHOST); |
| 160 | if( rc ){ |
| 161 | socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); |
| 162 | goto end_socket_open; |
| 163 | } |
| 164 | g.zIpAddr = mprintf("%s", zRemote); |
| 165 | iSocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| 166 | if( iSocket<0 ){ |
| 167 | socket_set_errmsg("cannot create a socket"); |
| 168 | rc = 1; |
| 169 | goto end_socket_open; |
| 170 | } |
| 171 | if( connect(iSocket,ai->ai_addr,ai->ai_addrlen)<0 ){ |
| 172 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 173 | pUrlData->port); |
| 174 | rc = 1; |
| 175 | goto end_socket_open; |
| 176 | } |
| 177 | #if !defined(_WIN32) |
| 178 | signal(SIGPIPE, SIG_IGN); |
| 179 | #endif |
| 180 | end_socket_open: |
| 181 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -137,10 +137,11 @@ | |
| 137 | ** Return the number of errors. |
| 138 | */ |
| 139 | int socket_open(UrlData *pUrlData){ |
| 140 | int rc = 0; |
| 141 | struct addrinfo *ai = 0; |
| 142 | struct addrinfo *p; |
| 143 | struct addrinfo hints; |
| 144 | char zPort[30]; |
| 145 | char zRemote[NI_MAXHOST]; |
| 146 | |
| 147 | socket_global_init(); |
| @@ -153,28 +154,29 @@ | |
| 154 | rc = getaddrinfo(pUrlData->name, zPort, &hints, &ai); |
| 155 | if( rc ){ |
| 156 | socket_set_errmsg("getaddrinfo() fails: %s", gai_strerror(rc)); |
| 157 | goto end_socket_open; |
| 158 | } |
| 159 | for(p=ai; p; p=p->ai_next){ |
| 160 | iSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); |
| 161 | if( iSocket<0 ) continue; |
| 162 | if( connect(iSocket,p->ai_addr,p->ai_addrlen)<0 ){ |
| 163 | socket_close(); |
| 164 | continue; |
| 165 | } |
| 166 | rc = getnameinfo(p->ai_addr, p->ai_addrlen, zRemote, sizeof(zRemote), |
| 167 | 0, 0, NI_NUMERICHOST); |
| 168 | if( rc ){ |
| 169 | socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); |
| 170 | goto end_socket_open; |
| 171 | } |
| 172 | g.zIpAddr = mprintf("%s", zRemote); |
| 173 | break; |
| 174 | } |
| 175 | if( p==0 ){ |
| 176 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 177 | pUrlData->port); |
| 178 | } |
| 179 | #if !defined(_WIN32) |
| 180 | signal(SIGPIPE, SIG_IGN); |
| 181 | #endif |
| 182 | end_socket_open: |
| 183 |