Fossil

Check-in [c24e1c27]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Clean getaddrinfo() code in src/http_socket.c incorporating suggestions from Gé Weijers Add getaddrinfo() code to src/cgi.c
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | ashish-ipv6
Files: files | file ages | folders
SHA1:c24e1c278580b243346486ce54050e11f2f1dd52
User & Date: ashish 2011-11-16 10:48:47
Original Comment: Clean getaddrinfo() code in http_socket.c incorporating suggestions from Gé Weijers
Context
2012-01-15
18:06
Merge latest changes from trunk check-in: b3130baa user: ashish tags: ashish-ipv6
2011-11-16
10:48
Clean getaddrinfo() code in src/http_socket.c incorporating suggestions from Gé Weijers Add getaddrinfo() code to src/cgi.c check-in: c24e1c27 user: ashish tags: ashish-ipv6
2011-11-13
09:11
Merge with trunk check-in: c30eaa88 user: ashish tags: ashish-ipv6
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cgi.c.

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
....
1251
1252
1253
1254
1255
1256
1257








1258
1259
1260
1261
1262

1263
1264
1265
1266











































1267

1268
1269
1270
1271
1272
1273
1274
....
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
....
1304
1305
1306
1307
1308
1309
1310

1311
1312
1313
1314
1315
1316
1317
  ){
    sa_family_t family;
    int v4mapped=0;
    if( remoteName.ss_family == AF_INET6 && 
        IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6*)&remoteName)->sin6_addr)) ){
        v4mapped = 1;
    }
    if(!getnameinfo((struct sockaddr*)&remoteName, remoteName.ss_len, zLine, sizeof(zLine),
                    NULL, 0, NI_NUMERICHOST)){
      zIpAddr = zLine;
    } else {
      zIpAddr = NULL;
    }
    if(zIpAddr && v4mapped) {
      /* ::ffff:172.16.0.2 */
................................................................................
  int listener = -1;           /* The server socket */
  int connection;              /* A socket for each individual connection */
  fd_set readfds;              /* Set of file descriptors for select() */
  socklen_t lenaddr;           /* Length of the inaddr structure */
  int child;                   /* PID of the child process */
  int nchildren = 0;           /* Number of child processes */
  struct timeval delay;        /* How long to wait inside select() */








#ifdef WITH_IPV6
  struct sockaddr_in6 inaddr;   /* The socket address */
#else
  struct sockaddr_in inaddr;   /* The socket address */
#endif

  int opt = 1;                 /* setsockopt flag */
  int iPort = mnPort;

  while( iPort<=mxPort ){











































    memset(&inaddr, 0, sizeof(inaddr));

#ifdef WITH_IPV6
    inaddr.sin6_family = AF_INET6;
#else
    inaddr.sin_family = AF_INET;
#endif
    if( flags & HTTP_SERVER_LOCALHOST ){
#ifdef WITH_IPV6
................................................................................
    inaddr.sin6_port = htons(iPort);
    listener = socket(AF_INET6, SOCK_STREAM, 0);
#else
    inaddr.sin_port = htons(iPort);
    listener = socket(AF_INET, SOCK_STREAM, 0);
#endif
    if( listener<0 ){
      iPort++;
      continue;
    }

    /* if we can't terminate nicely, at least allow the socket to be reused */
    setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

#ifdef WITH_IPV6
    opt=0;
................................................................................
#endif

    if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){
      close(listener);
      iPort++;
      continue;
    }

    break;
  }
  if( iPort>mxPort ){
    if( mnPort==mxPort ){
      fossil_fatal("unable to open listening socket on ports %d", mnPort);
    }else{
      fossil_fatal("unable to open listening socket on any"







|







 







>
>
>
>
>
>
>
>





>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>







 







|
<







 







>







1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
....
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
....
1340
1341
1342
1343
1344
1345
1346
1347

1348
1349
1350
1351
1352
1353
1354
....
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
  ){
    sa_family_t family;
    int v4mapped=0;
    if( remoteName.ss_family == AF_INET6 && 
        IN6_IS_ADDR_V4MAPPED(&(((struct sockaddr_in6*)&remoteName)->sin6_addr)) ){
        v4mapped = 1;
    }
    if(!getnameinfo((struct sockaddr*)&remoteName, size, zLine, sizeof(zLine),
                    NULL, 0, NI_NUMERICHOST)){
      zIpAddr = zLine;
    } else {
      zIpAddr = NULL;
    }
    if(zIpAddr && v4mapped) {
      /* ::ffff:172.16.0.2 */
................................................................................
  int listener = -1;           /* The server socket */
  int connection;              /* A socket for each individual connection */
  fd_set readfds;              /* Set of file descriptors for select() */
  socklen_t lenaddr;           /* Length of the inaddr structure */
  int child;                   /* PID of the child process */
  int nchildren = 0;           /* Number of child processes */
  struct timeval delay;        /* How long to wait inside select() */
#ifdef HAVE_GETADDRINFO
  struct addrinfo hints;
  struct addrinfo* res;
  struct addrinfo* i;
  struct sockaddr_storage inaddr;   /* The socket address */
  char* sPort;
  int iRet;
#else
#ifdef WITH_IPV6
  struct sockaddr_in6 inaddr;   /* The socket address */
#else
  struct sockaddr_in inaddr;   /* The socket address */
#endif
#endif
  int opt = 1;                 /* setsockopt flag */
  int iPort = mnPort;

  while( iPort<=mxPort ){
#ifdef HAVE_GETADDRINFO
    memset(&hints, 0, sizeof(struct addrinfo));
#ifdef WITH_IPV6
    hints.ai_family = PF_UNSPEC;
#else
    hints.ai_family = PF_INET;
#endif
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    if(!(flags & HTTP_SERVER_LOCALHOST)) hints.ai_flags |= AI_PASSIVE;

    sPort = mprintf("%d", iPort);

    if(iRet = getaddrinfo(NULL, sPort, &hints, &res)) {
      fossil_fatal("Unable to obtain address: %s", gai_strerror(iRet));
    }

    for(i = res; i; i = i->ai_next) {
      listener = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
      if(listener < 0) {
        fossil_fatal("Unable to create socket");
      }
	  opt=1;
      setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
      if(i->ai_family == AF_INET6) {
        opt=0;
        setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt));
      }
      if( bind(listener, i->ai_addr, i->ai_addrlen)<0 ){
        close(listener);
        listener = -1;
      }
	  break;
    }

    free(sPort);
    freeaddrinfo(res);

    if(listener == -1) {
      iPort++;
      continue;
    }
#else
    memset(&inaddr, 0, sizeof(inaddr));

#ifdef WITH_IPV6
    inaddr.sin6_family = AF_INET6;
#else
    inaddr.sin_family = AF_INET;
#endif
    if( flags & HTTP_SERVER_LOCALHOST ){
#ifdef WITH_IPV6
................................................................................
    inaddr.sin6_port = htons(iPort);
    listener = socket(AF_INET6, SOCK_STREAM, 0);
#else
    inaddr.sin_port = htons(iPort);
    listener = socket(AF_INET, SOCK_STREAM, 0);
#endif
    if( listener<0 ){
      fossil_fatal("Unable to create socket");

    }

    /* if we can't terminate nicely, at least allow the socket to be reused */
    setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

#ifdef WITH_IPV6
    opt=0;
................................................................................
#endif

    if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){
      close(listener);
      iPort++;
      continue;
    }
#endif
    break;
  }
  if( iPort>mxPort ){
    if( mnPort==mxPort ){
      fossil_fatal("unable to open listening socket on ports %d", mnPort);
    }else{
      fossil_fatal("unable to open listening socket on any"

Changes to src/http_socket.c.

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
  int error = 0;
#ifdef HAVE_GETADDRINFO
  struct addrinfo hints;
  struct addrinfo* res;
  struct addrinfo* i;
  char ip[INET6_ADDRSTRLEN];
  void* addr;


  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_flags = AI_ADDRCONFIG;
#ifdef WITH_IPV6
  hints.ai_family = PF_UNSPEC;
#else
  hints.ai_family = PF_INET;
#endif
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;



  if(getaddrinfo(g.urlName, NULL, &hints, &res)) {
    socket_set_errmsg("can't resolve host name: %s", g.urlName);

    return 1;
  }
  for(i = res; i; i = i->ai_next) {
    iSocket = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
    if(iSocket < 0) {
      continue;
    }
    if(i->ai_family == AF_INET) {
      ((struct sockaddr_in*)i->ai_addr)->sin_port = htons(g.urlPort);
    } else if(i->ai_family == AF_INET6) {
      ((struct sockaddr_in6*)i->ai_addr)->sin6_port = htons(g.urlPort);
    }
    if(connect(iSocket, i->ai_addr, i->ai_addrlen) < 0) {
      close(iSocket);
      iSocket = -1;
      continue;
    }
	if(!getnameinfo(i->ai_addr, i->ai_addrlen, ip, sizeof(ip),
					NULL, 0, NI_NUMERICHOST))
		g.zIpAddr = mprintf("%s", ip);

  }
  if(iSocket == -1) {
    socket_set_errmsg("cannot connect to host %s:%d", g.urlName, g.urlPort);
    error = 1;
  }

  freeaddrinfo(res);
#else
  static struct sockaddr_in addr;  /* The server address */
  static int addrIsInit = 0;       /* True once addr is initialized */

  socket_global_init();
  if( !addrIsInit ){







>










>
>
>
|

>







<
<
<
<
<





|
|
|
>


|


>







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
  int error = 0;
#ifdef HAVE_GETADDRINFO
  struct addrinfo hints;
  struct addrinfo* res;
  struct addrinfo* i;
  char ip[INET6_ADDRSTRLEN];
  void* addr;
  char* sPort;

  memset(&hints, 0, sizeof(struct addrinfo));
  hints.ai_flags = AI_ADDRCONFIG;
#ifdef WITH_IPV6
  hints.ai_family = PF_UNSPEC;
#else
  hints.ai_family = PF_INET;
#endif
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;

  sPort = mprintf("%d", g.urlPort);

  if(getaddrinfo(g.urlName, sPort, &hints, &res)) {
    socket_set_errmsg("can't resolve host name: %s", g.urlName);
    free(sPort);
    return 1;
  }
  for(i = res; i; i = i->ai_next) {
    iSocket = socket(i->ai_family, i->ai_socktype, i->ai_protocol);
    if(iSocket < 0) {
      continue;
    }





    if(connect(iSocket, i->ai_addr, i->ai_addrlen) < 0) {
      close(iSocket);
      iSocket = -1;
      continue;
    }
    if(!getnameinfo(i->ai_addr, i->ai_addrlen, ip, sizeof(ip),
                    NULL, 0, NI_NUMERICHOST))
        g.zIpAddr = mprintf("%s", ip);
    break;
  }
  if(iSocket == -1) {
    socket_set_errmsg("cannot connect to host %s:%s", g.urlName, sPort);
    error = 1;
  }
  free(sPort);
  freeaddrinfo(res);
#else
  static struct sockaddr_in addr;  /* The server address */
  static int addrIsInit = 0;       /* True once addr is initialized */

  socket_global_init();
  if( !addrIsInit ){