Fossil SCM
Alternative fix for the SSH remote-host problem for which Andy Bradford supplies a patch at [52f08008e2]: Continue to provide a numeric IP address, but try to get the IPv6 address if it is available, and always include the hostname in g.zIpAddr regardless of whether or not an IP address was found.
Commit
9bc7041ae74dfc097c981e88f42b0eb3018a4248
Parent
bcd7b488a2e11a7…
1 file changed
+15
-8
+15
-8
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -223,15 +223,22 @@ | ||
| 223 | 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | 225 | ** to which we connect. |
| 226 | 226 | */ |
| 227 | 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | - struct hostent *pHost; /* Used to make best effort for rcvfrom */ | |
| 229 | - struct sockaddr_in addr; | |
| 230 | - | |
| 231 | - memset(&addr, 0, sizeof(addr)); | |
| 232 | - pHost = gethostbyname(pUrlData->name); | |
| 233 | - if( pHost!=0 ){ | |
| 234 | - memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); | |
| 235 | - g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); | |
| 228 | + struct addrinfo *ai = 0; | |
| 229 | + struct addrinfo hints; | |
| 230 | + char zRemote[NI_MAXHOST]; | |
| 231 | + hints.ai_family = AF_UNSPEC; | |
| 232 | + hints.ai_socktype = SOCK_STREAM; | |
| 233 | + hints.ai_protocol = IPPROTO_TCP; | |
| 234 | + if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0 | |
| 235 | + && ai!=0 | |
| 236 | + && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, | |
| 237 | + sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){ | |
| 238 | + g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name); | |
| 239 | + } | |
| 240 | + if( ai ) freeaddrinfo(ai); | |
| 241 | + if( g.zIpAddr==0 ){ | |
| 242 | + g.zIpAddr = mprintf("%s", pUrlData->name); | |
| 236 | 243 | } |
| 237 | 244 | } |
| 238 | 245 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -223,15 +223,22 @@ | |
| 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | ** to which we connect. |
| 226 | */ |
| 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 229 | struct sockaddr_in addr; |
| 230 | |
| 231 | memset(&addr, 0, sizeof(addr)); |
| 232 | pHost = gethostbyname(pUrlData->name); |
| 233 | if( pHost!=0 ){ |
| 234 | memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); |
| 235 | g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); |
| 236 | } |
| 237 | } |
| 238 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -223,15 +223,22 @@ | |
| 223 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 224 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 225 | ** to which we connect. |
| 226 | */ |
| 227 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 228 | struct addrinfo *ai = 0; |
| 229 | struct addrinfo hints; |
| 230 | char zRemote[NI_MAXHOST]; |
| 231 | hints.ai_family = AF_UNSPEC; |
| 232 | hints.ai_socktype = SOCK_STREAM; |
| 233 | hints.ai_protocol = IPPROTO_TCP; |
| 234 | if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0 |
| 235 | && ai!=0 |
| 236 | && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, |
| 237 | sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){ |
| 238 | g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name); |
| 239 | } |
| 240 | if( ai ) freeaddrinfo(ai); |
| 241 | if( g.zIpAddr==0 ){ |
| 242 | g.zIpAddr = mprintf("%s", pUrlData->name); |
| 243 | } |
| 244 | } |
| 245 |