Fossil SCM
Use IPv6 for "fossil sync" when available.
Commit
1dbd4d0d0bd92e6da9e9631e56a9025a8a8172f4
Parent
0cdec7d290da52b…
2 files changed
+33
-35
+2
-2
+33
-35
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -45,11 +45,10 @@ | ||
| 45 | 45 | ** There can only be a single socket connection open at a time. |
| 46 | 46 | ** State information about that socket is stored in the following |
| 47 | 47 | ** local variables: |
| 48 | 48 | */ |
| 49 | 49 | static int socketIsInit = 0; /* True after global initialization */ |
| 50 | -static int addrIsInit = 0; /* True once addr is initialized */ | |
| 51 | 50 | #if defined(_WIN32) |
| 52 | 51 | static WSADATA socketInfo; /* Windows socket initialize data */ |
| 53 | 52 | #endif |
| 54 | 53 | static int iSocket = -1; /* The socket on which we talk to the server */ |
| 55 | 54 | static char *socketErrMsg = 0; /* Text of most recent socket error */ |
| @@ -106,11 +105,10 @@ | ||
| 106 | 105 | WSACleanup(); |
| 107 | 106 | #endif |
| 108 | 107 | socket_clear_errmsg(); |
| 109 | 108 | socketIsInit = 0; |
| 110 | 109 | } |
| 111 | - addrIsInit = 0; | |
| 112 | 110 | } |
| 113 | 111 | |
| 114 | 112 | /* |
| 115 | 113 | ** Close the currently open socket. If no socket is open, this routine |
| 116 | 114 | ** is a no-op. |
| @@ -134,54 +132,54 @@ | ||
| 134 | 132 | ** pUrlDAta->port TCP/IP port to use. Ex: 80 |
| 135 | 133 | ** |
| 136 | 134 | ** Return the number of errors. |
| 137 | 135 | */ |
| 138 | 136 | int socket_open(UrlData *pUrlData){ |
| 139 | - static struct sockaddr_in addr; /* The server address */ | |
| 137 | + int rc = 0; | |
| 138 | + struct addrinfo *ai = 0; | |
| 139 | + struct addrinfo hints; | |
| 140 | + char zPort[30]; | |
| 141 | + char zRemote[NI_MAXHOST]; | |
| 140 | 142 | |
| 141 | 143 | socket_global_init(); |
| 142 | - if( !addrIsInit ){ | |
| 143 | - memset(&addr, 0, sizeof(addr)); | |
| 144 | - addr.sin_family = AF_INET; | |
| 145 | - addr.sin_port = htons(pUrlData->port); | |
| 146 | - *(int*)&addr.sin_addr = inet_addr(pUrlData->name); | |
| 147 | - if( -1 == *(int*)&addr.sin_addr ){ | |
| 148 | -#ifndef FOSSIL_STATIC_LINK | |
| 149 | - struct hostent *pHost; | |
| 150 | - pHost = gethostbyname(pUrlData->name); | |
| 151 | - if( pHost!=0 ){ | |
| 152 | - memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); | |
| 153 | - }else | |
| 154 | -#endif | |
| 155 | - { | |
| 156 | - socket_set_errmsg("can't resolve host name: %s", pUrlData->name); | |
| 157 | - return 1; | |
| 158 | - } | |
| 159 | - } | |
| 160 | - addrIsInit = 1; | |
| 161 | - | |
| 162 | - /* Set the Global.zIpAddr variable to the server we are talking to. | |
| 163 | - ** This is used to populate the ipaddr column of the rcvfrom table, | |
| 164 | - ** if any files are received from the server. | |
| 165 | - */ | |
| 166 | - g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); | |
| 167 | - } | |
| 168 | - iSocket = socket(AF_INET,SOCK_STREAM,0); | |
| 144 | + memset(&hints, 0, sizeof(struct addrinfo)); | |
| 145 | + assert( iSocket<0 ); | |
| 146 | + hints.ai_family = AF_UNSPEC; | |
| 147 | + hints.ai_socktype = SOCK_STREAM; | |
| 148 | + hints.ai_protocol = IPPROTO_TCP; | |
| 149 | + sqlite3_snprintf(sizeof(zPort),zPort,"%d", pUrlData->port); | |
| 150 | + rc = getaddrinfo(pUrlData->name, zPort, &hints, &ai); | |
| 151 | + if( rc ){ | |
| 152 | + socket_set_errmsg("getaddrinfo() fails: %s", gai_strerror(rc)); | |
| 153 | + goto end_socket_open; | |
| 154 | + } | |
| 155 | + rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, sizeof(zRemote), | |
| 156 | + 0, 0, NI_NUMERICHOST); | |
| 157 | + if( rc ){ | |
| 158 | + socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); | |
| 159 | + goto end_socket_open; | |
| 160 | + } | |
| 161 | + g.zIpAddr = mprintf("%s", zRemote); | |
| 162 | + iSocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); | |
| 169 | 163 | if( iSocket<0 ){ |
| 170 | 164 | socket_set_errmsg("cannot create a socket"); |
| 171 | - return 1; | |
| 165 | + rc = 1; | |
| 166 | + goto end_socket_open; | |
| 172 | 167 | } |
| 173 | - if( connect(iSocket,(struct sockaddr*)&addr,sizeof(addr))<0 ){ | |
| 168 | + if( connect(iSocket,ai->ai_addr,ai->ai_addrlen)<0 ){ | |
| 174 | 169 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 175 | 170 | pUrlData->port); |
| 176 | - socket_close(); | |
| 177 | - return 1; | |
| 171 | + rc = 1; | |
| 172 | + goto end_socket_open; | |
| 178 | 173 | } |
| 179 | 174 | #if !defined(_WIN32) |
| 180 | 175 | signal(SIGPIPE, SIG_IGN); |
| 181 | 176 | #endif |
| 182 | - return 0; | |
| 177 | +end_socket_open: | |
| 178 | + if( rc && iSocket>=0 ) socket_close(); | |
| 179 | + if( ai ) freeaddrinfo(ai); | |
| 180 | + return rc; | |
| 183 | 181 | } |
| 184 | 182 | |
| 185 | 183 | /* |
| 186 | 184 | ** Send content out over the open socket connection. |
| 187 | 185 | */ |
| 188 | 186 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -45,11 +45,10 @@ | |
| 45 | ** There can only be a single socket connection open at a time. |
| 46 | ** State information about that socket is stored in the following |
| 47 | ** local variables: |
| 48 | */ |
| 49 | static int socketIsInit = 0; /* True after global initialization */ |
| 50 | static int addrIsInit = 0; /* True once addr is initialized */ |
| 51 | #if defined(_WIN32) |
| 52 | static WSADATA socketInfo; /* Windows socket initialize data */ |
| 53 | #endif |
| 54 | static int iSocket = -1; /* The socket on which we talk to the server */ |
| 55 | static char *socketErrMsg = 0; /* Text of most recent socket error */ |
| @@ -106,11 +105,10 @@ | |
| 106 | WSACleanup(); |
| 107 | #endif |
| 108 | socket_clear_errmsg(); |
| 109 | socketIsInit = 0; |
| 110 | } |
| 111 | addrIsInit = 0; |
| 112 | } |
| 113 | |
| 114 | /* |
| 115 | ** Close the currently open socket. If no socket is open, this routine |
| 116 | ** is a no-op. |
| @@ -134,54 +132,54 @@ | |
| 134 | ** pUrlDAta->port TCP/IP port to use. Ex: 80 |
| 135 | ** |
| 136 | ** Return the number of errors. |
| 137 | */ |
| 138 | int socket_open(UrlData *pUrlData){ |
| 139 | static struct sockaddr_in addr; /* The server address */ |
| 140 | |
| 141 | socket_global_init(); |
| 142 | if( !addrIsInit ){ |
| 143 | memset(&addr, 0, sizeof(addr)); |
| 144 | addr.sin_family = AF_INET; |
| 145 | addr.sin_port = htons(pUrlData->port); |
| 146 | *(int*)&addr.sin_addr = inet_addr(pUrlData->name); |
| 147 | if( -1 == *(int*)&addr.sin_addr ){ |
| 148 | #ifndef FOSSIL_STATIC_LINK |
| 149 | struct hostent *pHost; |
| 150 | pHost = gethostbyname(pUrlData->name); |
| 151 | if( pHost!=0 ){ |
| 152 | memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); |
| 153 | }else |
| 154 | #endif |
| 155 | { |
| 156 | socket_set_errmsg("can't resolve host name: %s", pUrlData->name); |
| 157 | return 1; |
| 158 | } |
| 159 | } |
| 160 | addrIsInit = 1; |
| 161 | |
| 162 | /* Set the Global.zIpAddr variable to the server we are talking to. |
| 163 | ** This is used to populate the ipaddr column of the rcvfrom table, |
| 164 | ** if any files are received from the server. |
| 165 | */ |
| 166 | g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); |
| 167 | } |
| 168 | iSocket = socket(AF_INET,SOCK_STREAM,0); |
| 169 | if( iSocket<0 ){ |
| 170 | socket_set_errmsg("cannot create a socket"); |
| 171 | return 1; |
| 172 | } |
| 173 | if( connect(iSocket,(struct sockaddr*)&addr,sizeof(addr))<0 ){ |
| 174 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 175 | pUrlData->port); |
| 176 | socket_close(); |
| 177 | return 1; |
| 178 | } |
| 179 | #if !defined(_WIN32) |
| 180 | signal(SIGPIPE, SIG_IGN); |
| 181 | #endif |
| 182 | return 0; |
| 183 | } |
| 184 | |
| 185 | /* |
| 186 | ** Send content out over the open socket connection. |
| 187 | */ |
| 188 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -45,11 +45,10 @@ | |
| 45 | ** There can only be a single socket connection open at a time. |
| 46 | ** State information about that socket is stored in the following |
| 47 | ** local variables: |
| 48 | */ |
| 49 | static int socketIsInit = 0; /* True after global initialization */ |
| 50 | #if defined(_WIN32) |
| 51 | static WSADATA socketInfo; /* Windows socket initialize data */ |
| 52 | #endif |
| 53 | static int iSocket = -1; /* The socket on which we talk to the server */ |
| 54 | static char *socketErrMsg = 0; /* Text of most recent socket error */ |
| @@ -106,11 +105,10 @@ | |
| 105 | WSACleanup(); |
| 106 | #endif |
| 107 | socket_clear_errmsg(); |
| 108 | socketIsInit = 0; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | /* |
| 113 | ** Close the currently open socket. If no socket is open, this routine |
| 114 | ** is a no-op. |
| @@ -134,54 +132,54 @@ | |
| 132 | ** pUrlDAta->port TCP/IP port to use. Ex: 80 |
| 133 | ** |
| 134 | ** Return the number of errors. |
| 135 | */ |
| 136 | int socket_open(UrlData *pUrlData){ |
| 137 | int rc = 0; |
| 138 | struct addrinfo *ai = 0; |
| 139 | struct addrinfo hints; |
| 140 | char zPort[30]; |
| 141 | char zRemote[NI_MAXHOST]; |
| 142 | |
| 143 | socket_global_init(); |
| 144 | memset(&hints, 0, sizeof(struct addrinfo)); |
| 145 | assert( iSocket<0 ); |
| 146 | hints.ai_family = AF_UNSPEC; |
| 147 | hints.ai_socktype = SOCK_STREAM; |
| 148 | hints.ai_protocol = IPPROTO_TCP; |
| 149 | sqlite3_snprintf(sizeof(zPort),zPort,"%d", pUrlData->port); |
| 150 | rc = getaddrinfo(pUrlData->name, zPort, &hints, &ai); |
| 151 | if( rc ){ |
| 152 | socket_set_errmsg("getaddrinfo() fails: %s", gai_strerror(rc)); |
| 153 | goto end_socket_open; |
| 154 | } |
| 155 | rc = getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote, sizeof(zRemote), |
| 156 | 0, 0, NI_NUMERICHOST); |
| 157 | if( rc ){ |
| 158 | socket_set_errmsg("getnameinfo() failed: %s", gai_strerror(rc)); |
| 159 | goto end_socket_open; |
| 160 | } |
| 161 | g.zIpAddr = mprintf("%s", zRemote); |
| 162 | iSocket = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); |
| 163 | if( iSocket<0 ){ |
| 164 | socket_set_errmsg("cannot create a socket"); |
| 165 | rc = 1; |
| 166 | goto end_socket_open; |
| 167 | } |
| 168 | if( connect(iSocket,ai->ai_addr,ai->ai_addrlen)<0 ){ |
| 169 | socket_set_errmsg("cannot connect to host %s:%d", pUrlData->name, |
| 170 | pUrlData->port); |
| 171 | rc = 1; |
| 172 | goto end_socket_open; |
| 173 | } |
| 174 | #if !defined(_WIN32) |
| 175 | signal(SIGPIPE, SIG_IGN); |
| 176 | #endif |
| 177 | end_socket_open: |
| 178 | if( rc && iSocket>=0 ) socket_close(); |
| 179 | if( ai ) freeaddrinfo(ai); |
| 180 | return rc; |
| 181 | } |
| 182 | |
| 183 | /* |
| 184 | ** Send content out over the open socket connection. |
| 185 | */ |
| 186 |
+2
-2
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1966,12 +1966,12 @@ | ||
| 1966 | 1966 | g.clockSkewSeen = 1; |
| 1967 | 1967 | } |
| 1968 | 1968 | |
| 1969 | 1969 | fossil_force_newline(); |
| 1970 | 1970 | fossil_print( |
| 1971 | - "%s finished with %lld bytes sent, %lld bytes received\n", | |
| 1972 | - zOpType, nSent, nRcvd); | |
| 1971 | + "Total bytes sent: %lld received: %lld ip: %s\n", | |
| 1972 | + nSent, nRcvd, g.zIpAddr); | |
| 1973 | 1973 | transport_close(&g.url); |
| 1974 | 1974 | transport_global_shutdown(&g.url); |
| 1975 | 1975 | if( nErr && go==2 ){ |
| 1976 | 1976 | db_multi_exec("DROP TABLE onremote"); |
| 1977 | 1977 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1978 | 1978 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1966,12 +1966,12 @@ | |
| 1966 | g.clockSkewSeen = 1; |
| 1967 | } |
| 1968 | |
| 1969 | fossil_force_newline(); |
| 1970 | fossil_print( |
| 1971 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1972 | zOpType, nSent, nRcvd); |
| 1973 | transport_close(&g.url); |
| 1974 | transport_global_shutdown(&g.url); |
| 1975 | if( nErr && go==2 ){ |
| 1976 | db_multi_exec("DROP TABLE onremote"); |
| 1977 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1978 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1966,12 +1966,12 @@ | |
| 1966 | g.clockSkewSeen = 1; |
| 1967 | } |
| 1968 | |
| 1969 | fossil_force_newline(); |
| 1970 | fossil_print( |
| 1971 | "Total bytes sent: %lld received: %lld ip: %s\n", |
| 1972 | nSent, nRcvd, g.zIpAddr); |
| 1973 | transport_close(&g.url); |
| 1974 | transport_global_shutdown(&g.url); |
| 1975 | if( nErr && go==2 ){ |
| 1976 | db_multi_exec("DROP TABLE onremote"); |
| 1977 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1978 |