Changes On Branch ipv6
Not logged in

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
41
42
43
44
45
46

47
48
49
50
51
52
53
....
1117
1118
1119
1120
1121
1122
1123











1124
1125
1126
1127
1128
1129
1130
....
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166




1167
1168
1169
1170
1171
1172
1173
#ifdef __EMX__
  typedef int socklen_t;
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "cgi.h"

#if INTERFACE
/*
** Shortcuts for cgi_parameter.  P("x") returns the value of query parameter
** or cookie "x", or NULL if there is no such parameter or cookie.  PD("x","y")
** does the same except "y" is returned in place of NULL if there is not match.
................................................................................
    zInput++;
    while( fossil_isspace(*zInput) ){ zInput++; }
  }
  if( zLeftOver ){ *zLeftOver = zInput; }
  return zResult;
}












/*
** This routine handles a single HTTP request which is coming in on
** standard input and which replies on standard output.
**
** The HTTP request is read from standard input and is used to initialize
** environment variables as per CGI.  The cgi_init() routine to complete
** the setup.  Once all the setup is finished, this procedure returns
................................................................................
    malformed_request();
  }
  cgi_setenv("REQUEST_URI", zToken);
  for(i=0; zToken[i] && zToken[i]!='?'; i++){}
  if( zToken[i] ) zToken[i++] = 0;
  cgi_setenv("PATH_INFO", zToken);
  cgi_setenv("QUERY_STRING", &zToken[i]);
  if( zIpAddr==0 &&
        getpeername(fileno(g.httpIn), (struct sockaddr*)&remoteName, 
                                &size)>=0
  ){
    zIpAddr = inet_ntoa(remoteName.sin_addr);




  }
  if( zIpAddr ){   
    cgi_setenv("REMOTE_ADDR", zIpAddr);
    g.zIpAddr = mprintf("%s", zIpAddr);
  }
 
  /* Get all the optional fields that follow the first line.






>







 







>
>
>
>
>
>
>
>
>
>
>







 







|
|
|
|
|
>
>
>
>







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
....
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
....
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
#ifdef __EMX__
  typedef int socklen_t;
#endif
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include "cgi.h"

#if INTERFACE
/*
** Shortcuts for cgi_parameter.  P("x") returns the value of query parameter
** or cookie "x", or NULL if there is no such parameter or cookie.  PD("x","y")
** does the same except "y" is returned in place of NULL if there is not match.
................................................................................
    zInput++;
    while( fossil_isspace(*zInput) ){ zInput++; }
  }
  if( zLeftOver ){ *zLeftOver = zInput; }
  return zResult;
}

/*
** All possible forms of an IP address.  Needed to work around GCC strict
** aliasing rules.
*/
typedef union {
  struct sockaddr sa;              /* Abstract superclass */
  struct sockaddr_in sa4;          /* IPv4 */
  struct sockaddr_in6 sa6;         /* IPv6 */
  struct sockaddr_storage sas;     /* Should be the maximum of the above 3 */
} address;

/*
** This routine handles a single HTTP request which is coming in on
** standard input and which replies on standard output.
**
** The HTTP request is read from standard input and is used to initialize
** environment variables as per CGI.  The cgi_init() routine to complete
** the setup.  Once all the setup is finished, this procedure returns
................................................................................
    malformed_request();
  }
  cgi_setenv("REQUEST_URI", zToken);
  for(i=0; zToken[i] && zToken[i]!='?'; i++){}
  if( zToken[i] ) zToken[i++] = 0;
  cgi_setenv("PATH_INFO", zToken);
  cgi_setenv("QUERY_STRING", &zToken[i]);
  if( zIpAddr==0 ){
    address remoteAddr;
    unsigned int size = sizeof(remoteAddr);
    char zHost[NI_MAXHOST];
    if( getpeername(fileno(g.httpIn), &remoteAddr.sa, &size)>=0 ){
      getnameinfo(&remoteAddr.sa, size, zHost, sizeof(zHost), 0, 0,
                  NI_NUMERICHOST);
      zIpAddr = mprintf("%s", zHost);
    }
  }
  if( zIpAddr ){   
    cgi_setenv("REMOTE_ADDR", zIpAddr);
    g.zIpAddr = mprintf("%s", zIpAddr);
  }
 
  /* Get all the optional fields that follow the first line.

Changes to src/http_socket.c.

39
40
41
42
43
44
45

46
47
48
49
50
51
52
...
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156







157
158

159


160
161
162
163
164
165
166
167
168


169
170
171
172

173
174
175


176













177
178
179
180
181
182
183
#  include <arpa/inet.h>
#  include <sys/socket.h>
#  include <netdb.h>
#endif
#include <assert.h>
#include <sys/types.h>
#include <signal.h>


/*
** There can only be a single socket connection open at a time.
** State information about that socket is stored in the following
** local variables:
*/
static int socketIsInit = 0;    /* True after global initialization */
................................................................................
**    g.urlName       Name of the server.  Ex: www.fossil-scm.org
**    g.urlPort       TCP/IP port to use.  Ex: 80
**
** Return the number of errors.
*/
int socket_open(void){
  static struct sockaddr_in addr;  /* The server address */
  static int addrIsInit = 0;       /* True once addr is initialized */


  socket_global_init();
  if( !addrIsInit ){
    addr.sin_family = AF_INET;
    addr.sin_port = htons(g.urlPort);
    *(int*)&addr.sin_addr = inet_addr(g.urlName);
    if( -1 == *(int*)&addr.sin_addr ){
#ifndef FOSSIL_STATIC_LINK
      struct hostent *pHost;
      pHost = gethostbyname(g.urlName);
      if( pHost!=0 ){
        memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length);
      }else
#endif
      {







        socket_set_errmsg("can't resolve host name: %s", g.urlName);
        return 1;

      }


    }
    addrIsInit = 1;

    /* Set the Global.zIpAddr variable to the server we are talking to.
    ** This is used to populate the ipaddr column of the rcvfrom table,
    ** if any files are received from the server.
    */
    g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr));
  }


  iSocket = socket(AF_INET,SOCK_STREAM,0);
  if( iSocket<0 ){
    socket_set_errmsg("cannot create a socket");
    return 1;

  }
  if( connect(iSocket,(struct sockaddr*)&addr,sizeof(addr))<0 ){
    socket_set_errmsg("cannot connect to host %s:%d", g.urlName, g.urlPort);


    socket_close();













    return 1;
  }
#if !defined(_WIN32)
  signal(SIGPIPE, SIG_IGN);
#endif
  return 0;
}






>







 







|
>



<
|
|
|
<
<
<
<
<
<
<
|
>
>
>
>
>
>
>
|
|
>
|
>
>


|
<
<
<
<
<
|
>
>
|
|
|
|
>
|
<
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
...
135
136
137
138
139
140
141
142
143
144
145
146

147
148
149







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166





167
168
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#  include <arpa/inet.h>
#  include <sys/socket.h>
#  include <netdb.h>
#endif
#include <assert.h>
#include <sys/types.h>
#include <signal.h>
#include <errno.h>

/*
** There can only be a single socket connection open at a time.
** State information about that socket is stored in the following
** local variables:
*/
static int socketIsInit = 0;    /* True after global initialization */
................................................................................
**    g.urlName       Name of the server.  Ex: www.fossil-scm.org
**    g.urlPort       TCP/IP port to use.  Ex: 80
**
** Return the number of errors.
*/
int socket_open(void){
  static struct sockaddr_in addr;  /* The server address */
  static int addrIsInit = 0;       /* True when initialized once */
  static struct addrinfo *p = 0;   /* Succcessful open */

  socket_global_init();
  if( !addrIsInit ){

    struct addrinfo sHints;
    int rc;
    char zPort[30];







    
    memset(&sHints, 0, sizeof(sHints));
    sHints.ai_family = AF_UNSPEC;
    sHints.ai_socktype = SOCK_STREAM;
    sHints.ai_flags = 0;
    sHints.ai_protocol = 0;
    sqlite3_snprintf(sizeof(zPort), zPort, "%d", g.urlPort);
    rc = getaddrinfo(g.urlName, zPort, &sHints, &p);
    if( rc!=0 ){
      fossil_fatal("getaddrinfo(\"%s\",\"%s\",...): %s",
                   g.urlName, zPort, gai_strerror(rc));
    }
    if( p==0 ){
      fossil_fatal("no IP addresses returned by getaddrinfo()");
    }
    addrIsInit = 1;
  }






  while( p ){
    char zHost[NI_MAXHOST];
    iSocket = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
    if( iSocket<0 ){
      fossil_warning("socket() failed: %s", strerror(errno));
      p = p->ai_next;
      continue;
    }

    if( connect(iSocket, p->ai_addr, p->ai_addrlen)<0 ){
      fossil_warning("connect() failed: %s", strerror(errno));
      p = p->ai_next;
      socket_close();
      continue;
    }
    p->ai_next = 0;
    if( getnameinfo(p->ai_addr, p->ai_addrlen, zHost, sizeof(zHost),
                    0, 0, NI_NUMERICHOST)==0 ){
      g.zIpAddr = mprintf("%s", zHost);
    }else{
      fossil_fatal("cannot find numeric host IP address");
    }
    break;
  }
  if( p==0 ){
    socket_set_errmsg("cannot create a socket");
    return 1;
  }
#if !defined(_WIN32)
  signal(SIGPIPE, SIG_IGN);
#endif
  return 0;
}

Changes to src/url.c.

99
100
101
102
103
104
105


106



107





108
109
110
111
112
113
114
      }else{
        zLogin = mprintf("%t@", g.urlUser);
      }
      for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
      g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
      i = j;
    }else{


      for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}



      g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);





      zLogin = mprintf("");
    }
    url_tolower(g.urlName);
    if( c==':' ){
      g.urlPort = 0;
      i++;
      while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){






>
>
|
>
>
>

>
>
>
>
>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
      }else{
        zLogin = mprintf("%t@", g.urlUser);
      }
      for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
      g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
      i = j;
    }else{
      int inSquare = 0;
      int n;
      for(i=iStart; (c=zUrl[i])!=0 && c!='/' && (inSquare || c!=':'); i++){
        if( c=='[' ) inSquare = 1;
        if( c==']' ) inSquare = 0;
      }
      g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]);
      n = strlen(g.urlName);
      if( g.urlName[0]=='[' && n>2 && g.urlName[n-1]==']' ){
        g.urlName++;
        g.urlName[n-2] = 0;
      }
      zLogin = mprintf("");
    }
    url_tolower(g.urlName);
    if( c==':' ){
      g.urlPort = 0;
      i++;
      while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){