Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch ipv6 Excluding Merge-Ins
This is equivalent to a diff from e40e79b7ab to 89fb414274
2012-07-07
| ||
14:07 | Update the inetd handler so that it works with IPv6. Leaf check-in: 89fb414274 user: drh tags: ipv6 | |
13:32 | Fix the URL parser so that it is able to handle IPv6 addresses. Fixes to the IPv6 client-side code. check-in: beea59873a user: drh tags: ipv6 | |
2012-07-06
| ||
16:18 | /json/query now fails without executing the query if the provided query has no result _columns_ (to explicitly disallow INSERT/DELETE/DROP, etc.). check-in: 3e1dd97f77 user: stephan tags: trunk | |
2012-07-05
| ||
21:25 | Work toward getting Fossil to be able to sync over IPV6. This check-in compiles, but we do not yet have a server to test it on. check-in: 0268e771ef user: drh tags: ipv6 | |
19:24 | Minor interal json refactoring made possible by recent cson changes. check-in: e40e79b7ab user: stephan tags: trunk | |
19:03 | Pulled in latest cson amalgamation for the cson_type_id addition and started refactoring some O(N) lookups to O(1) based on that addition. check-in: cde55bd7a3 user: stephan tags: trunk | |
Changes to src/cgi.c.
40 40 #ifdef __EMX__ 41 41 typedef int socklen_t; 42 42 #endif 43 43 #include <time.h> 44 44 #include <stdio.h> 45 45 #include <stdlib.h> 46 46 #include <unistd.h> 47 +#include <netdb.h> 47 48 #include "cgi.h" 48 49 49 50 #if INTERFACE 50 51 /* 51 52 ** Shortcuts for cgi_parameter. P("x") returns the value of query parameter 52 53 ** or cookie "x", or NULL if there is no such parameter or cookie. PD("x","y") 53 54 ** does the same except "y" is returned in place of NULL if there is not match. ................................................................................ 1117 1118 zInput++; 1118 1119 while( fossil_isspace(*zInput) ){ zInput++; } 1119 1120 } 1120 1121 if( zLeftOver ){ *zLeftOver = zInput; } 1121 1122 return zResult; 1122 1123 } 1123 1124 1125 +/* 1126 +** All possible forms of an IP address. Needed to work around GCC strict 1127 +** aliasing rules. 1128 +*/ 1129 +typedef union { 1130 + struct sockaddr sa; /* Abstract superclass */ 1131 + struct sockaddr_in sa4; /* IPv4 */ 1132 + struct sockaddr_in6 sa6; /* IPv6 */ 1133 + struct sockaddr_storage sas; /* Should be the maximum of the above 3 */ 1134 +} address; 1135 + 1124 1136 /* 1125 1137 ** This routine handles a single HTTP request which is coming in on 1126 1138 ** standard input and which replies on standard output. 1127 1139 ** 1128 1140 ** The HTTP request is read from standard input and is used to initialize 1129 1141 ** environment variables as per CGI. The cgi_init() routine to complete 1130 1142 ** the setup. Once all the setup is finished, this procedure returns ................................................................................ 1155 1167 malformed_request(); 1156 1168 } 1157 1169 cgi_setenv("REQUEST_URI", zToken); 1158 1170 for(i=0; zToken[i] && zToken[i]!='?'; i++){} 1159 1171 if( zToken[i] ) zToken[i++] = 0; 1160 1172 cgi_setenv("PATH_INFO", zToken); 1161 1173 cgi_setenv("QUERY_STRING", &zToken[i]); 1162 - if( zIpAddr==0 && 1163 - getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 1164 - &size)>=0 1165 - ){ 1166 - zIpAddr = inet_ntoa(remoteName.sin_addr); 1174 + if( zIpAddr==0 ){ 1175 + address remoteAddr; 1176 + unsigned int size = sizeof(remoteAddr); 1177 + char zHost[NI_MAXHOST]; 1178 + if( getpeername(fileno(g.httpIn), &remoteAddr.sa, &size)>=0 ){ 1179 + getnameinfo(&remoteAddr.sa, size, zHost, sizeof(zHost), 0, 0, 1180 + NI_NUMERICHOST); 1181 + zIpAddr = mprintf("%s", zHost); 1182 + } 1167 1183 } 1168 1184 if( zIpAddr ){ 1169 1185 cgi_setenv("REMOTE_ADDR", zIpAddr); 1170 1186 g.zIpAddr = mprintf("%s", zIpAddr); 1171 1187 } 1172 1188 1173 1189 /* Get all the optional fields that follow the first line.
Changes to src/http_socket.c.
39 39 # include <arpa/inet.h> 40 40 # include <sys/socket.h> 41 41 # include <netdb.h> 42 42 #endif 43 43 #include <assert.h> 44 44 #include <sys/types.h> 45 45 #include <signal.h> 46 +#include <errno.h> 46 47 47 48 /* 48 49 ** There can only be a single socket connection open at a time. 49 50 ** State information about that socket is stored in the following 50 51 ** local variables: 51 52 */ 52 53 static int socketIsInit = 0; /* True after global initialization */ ................................................................................ 134 135 ** g.urlName Name of the server. Ex: www.fossil-scm.org 135 136 ** g.urlPort TCP/IP port to use. Ex: 80 136 137 ** 137 138 ** Return the number of errors. 138 139 */ 139 140 int socket_open(void){ 140 141 static struct sockaddr_in addr; /* The server address */ 141 - static int addrIsInit = 0; /* True once addr is initialized */ 142 + static int addrIsInit = 0; /* True when initialized once */ 143 + static struct addrinfo *p = 0; /* Succcessful open */ 142 144 143 145 socket_global_init(); 144 146 if( !addrIsInit ){ 145 - addr.sin_family = AF_INET; 146 - addr.sin_port = htons(g.urlPort); 147 - *(int*)&addr.sin_addr = inet_addr(g.urlName); 148 - if( -1 == *(int*)&addr.sin_addr ){ 149 -#ifndef FOSSIL_STATIC_LINK 150 - struct hostent *pHost; 151 - pHost = gethostbyname(g.urlName); 152 - if( pHost!=0 ){ 153 - memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length); 154 - }else 155 -#endif 156 - { 157 - socket_set_errmsg("can't resolve host name: %s", g.urlName); 158 - return 1; 159 - } 147 + struct addrinfo sHints; 148 + int rc; 149 + char zPort[30]; 150 + 151 + memset(&sHints, 0, sizeof(sHints)); 152 + sHints.ai_family = AF_UNSPEC; 153 + sHints.ai_socktype = SOCK_STREAM; 154 + sHints.ai_flags = 0; 155 + sHints.ai_protocol = 0; 156 + sqlite3_snprintf(sizeof(zPort), zPort, "%d", g.urlPort); 157 + rc = getaddrinfo(g.urlName, zPort, &sHints, &p); 158 + if( rc!=0 ){ 159 + fossil_fatal("getaddrinfo(\"%s\",\"%s\",...): %s", 160 + g.urlName, zPort, gai_strerror(rc)); 161 + } 162 + if( p==0 ){ 163 + fossil_fatal("no IP addresses returned by getaddrinfo()"); 160 164 } 161 165 addrIsInit = 1; 166 + } 162 167 163 - /* Set the Global.zIpAddr variable to the server we are talking to. 164 - ** This is used to populate the ipaddr column of the rcvfrom table, 165 - ** if any files are received from the server. 166 - */ 167 - g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr)); 168 - } 169 - iSocket = socket(AF_INET,SOCK_STREAM,0); 170 - if( iSocket<0 ){ 171 - socket_set_errmsg("cannot create a socket"); 172 - return 1; 168 + while( p ){ 169 + char zHost[NI_MAXHOST]; 170 + iSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol); 171 + if( iSocket<0 ){ 172 + fossil_warning("socket() failed: %s", strerror(errno)); 173 + p = p->ai_next; 174 + continue; 175 + } 176 + if( connect(iSocket, p->ai_addr, p->ai_addrlen)<0 ){ 177 + fossil_warning("connect() failed: %s", strerror(errno)); 178 + p = p->ai_next; 179 + socket_close(); 180 + continue; 181 + } 182 + p->ai_next = 0; 183 + if( getnameinfo(p->ai_addr, p->ai_addrlen, zHost, sizeof(zHost), 184 + 0, 0, NI_NUMERICHOST)==0 ){ 185 + g.zIpAddr = mprintf("%s", zHost); 186 + }else{ 187 + fossil_fatal("cannot find numeric host IP address"); 188 + } 189 + break; 173 190 } 174 - if( connect(iSocket,(struct sockaddr*)&addr,sizeof(addr))<0 ){ 175 - socket_set_errmsg("cannot connect to host %s:%d", g.urlName, g.urlPort); 176 - socket_close(); 191 + if( p==0 ){ 192 + socket_set_errmsg("cannot create a socket"); 177 193 return 1; 178 194 } 179 195 #if !defined(_WIN32) 180 196 signal(SIGPIPE, SIG_IGN); 181 197 #endif 182 198 return 0; 183 199 }
Changes to src/url.c.
99 99 }else{ 100 100 zLogin = mprintf("%t@", g.urlUser); 101 101 } 102 102 for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} 103 103 g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]); 104 104 i = j; 105 105 }else{ 106 - for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){} 106 + int inSquare = 0; 107 + int n; 108 + for(i=iStart; (c=zUrl[i])!=0 && c!='/' && (inSquare || c!=':'); i++){ 109 + if( c=='[' ) inSquare = 1; 110 + if( c==']' ) inSquare = 0; 111 + } 107 112 g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]); 113 + n = strlen(g.urlName); 114 + if( g.urlName[0]=='[' && n>2 && g.urlName[n-1]==']' ){ 115 + g.urlName++; 116 + g.urlName[n-2] = 0; 117 + } 108 118 zLogin = mprintf(""); 109 119 } 110 120 url_tolower(g.urlName); 111 121 if( c==':' ){ 112 122 g.urlPort = 0; 113 123 i++; 114 124 while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){