Fossil

Check-in [1627571b]
Login

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

Overview
Comment:Get "fossil server" working for IPv6 on MinGW, using hints from Olivier Mascia.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | win-server-ipv6
Files: files | file ages | folders
SHA3-256:1627571be979436336fc7a0b5d088c60f8ed80e2fdefe8e99d604b7191c9c0d2
User & Date: drh 2018-01-01 18:48:44
Context
2018-01-01
18:56
The "fossil server" command on windows now listens for both IPv4 and IPv6 connections. check-in: 21d5038f user: drh tags: trunk
18:48
Get "fossil server" working for IPv6 on MinGW, using hints from Olivier Mascia. Closed-Leaf check-in: 1627571b user: drh tags: win-server-ipv6
2017-12-31
20:02
Fix a C89 variable declaration that prevents compiling on older versions of MSVC. check-in: 80b3b127 user: drh tags: win-server-ipv6
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/winhttp.c.

    19     19   ** for windows. It also implements a Windows Service which allows the HTTP
    20     20   ** server to be run without any user logged on.
    21     21   */
    22     22   #include "config.h"
    23     23   #ifdef _WIN32
    24     24   /* This code is for win32 only */
    25     25   #include <ws2tcpip.h>
    26         -#include <mstcpip.h>
    27     26   #include <windows.h>
    28     27   #include <process.h>
    29     28   #include "winhttp.h"
           29  +
           30  +#ifndef IPV6_V6ONLY
           31  +# define IPV6_V6ONLY 27  /* Because this definition is missing in MinGW */
           32  +#endif
    30     33   
    31     34   /*
    32     35   ** The HttpServer structure holds information about an instance of
    33     36   ** the HTTP server itself.
    34     37   */
    35     38   typedef struct HttpServer HttpServer;
    36     39   struct HttpServer {
................................................................................
   323    326     const char *zIpAddr,      /* Bind to this IP address, if not NULL */
   324    327     int flags                 /* One or more HTTP_SERVER_ flags */
   325    328   ){
   326    329     HANDLE hStoppedEvent;
   327    330     WSADATA wd;
   328    331     SOCKET s = INVALID_SOCKET;
   329    332     SOCKADDR_IN6 addr;
          333  +  int addrlen;
   330    334     int idCnt = 0;
   331    335     int iPort = mnPort;
   332    336     Blob options;
   333    337     wchar_t zTmpPath[MAX_PATH];
   334    338     const char *zSkin;
   335    339   #if USE_SEE
   336    340     const char *zSavedKey = 0;
................................................................................
   364    368     zSavedKey = db_get_saved_encryption_key();
   365    369     savedKeySize = db_get_saved_encryption_key_size();
   366    370     if( zSavedKey!=0 && savedKeySize>0 ){
   367    371       blob_appendf(&options, " --usepidkey %lu:%p:%u", GetCurrentProcessId(),
   368    372                    zSavedKey, savedKeySize);
   369    373     }
   370    374   #endif
   371         -  if( WSAStartup(MAKEWORD(1,1), &wd) ){
          375  +  if( WSAStartup(MAKEWORD(2,0), &wd) ){
   372    376       fossil_fatal("unable to initialize winsock");
          377  +  }
          378  +  if( flags & HTTP_SERVER_LOCALHOST ){
          379  +    zIpAddr = "127.0.0.1";
   373    380     }
   374    381     while( iPort<=mxPort ){
   375    382       DWORD ipv6only = 0;
   376    383       s = socket(AF_INET6, SOCK_STREAM, 0);
   377    384       if( s==INVALID_SOCKET ){
   378    385         fossil_fatal("unable to create a socket");
   379    386       }
   380    387       setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only,
   381    388                  sizeof(ipv6only));
          389  +    memset(&addr, 0, sizeof(addr));
          390  +    addrlen = sizeof(addr);
   382    391       if( zIpAddr ){
   383         -      int addrlen = sizeof(addr);
   384         -      memset(&addr, 0, sizeof(addr));
          392  +      char* zIp;
          393  +      if( strstr(zIpAddr, ".") ){
          394  +        zIp = mprintf("::ffff:%s", zIpAddr);
          395  +      }else{
          396  +        zIp = mprintf("%s", zIpAddr);
          397  +      }
   385    398         addr.sin6_family = AF_INET6;
   386         -      if (WSAStringToAddress((LPSTR)zIpAddr, AF_INET6, NULL,
          399  +      if (WSAStringToAddress(zIp, AF_INET6, NULL,
   387    400                                (struct sockaddr *)&addr, &addrlen) != 0){
   388         -        SOCKADDR_IN addrv4;
   389         -        SCOPE_ID scope;
   390         -        int addrlen = sizeof(addrv4);
   391         -        memset(&addrv4, 0, sizeof(addrv4));
   392         -        addrv4.sin_family = AF_INET;
   393         -        if (WSAStringToAddress((LPSTR)zIpAddr, AF_INET, NULL,
   394         -                               (struct sockaddr *)&addrv4, &addrlen) != 0){
   395         -          fossil_fatal("not a valid IP address: %s", zIpAddr);
   396         -        }
   397         -        memset(&addr, 0, sizeof(addr));
   398         -        memset(&scope, 0, sizeof(scope));
   399         -        IN6ADDR_SETV4MAPPED(&addr, &addrv4.sin_addr, scope, htons(iPort));
   400         -      }else{
   401         -        ((SOCKADDR_IN6*)&addr)->sin6_port = htons(iPort);
          401  +        fossil_fatal("not a valid IP address: %s", zIpAddr);
   402    402         }
   403         -    }else if( flags & HTTP_SERVER_LOCALHOST ){
   404         -      SCOPE_ID scope;
   405         -      memset(&addr, 0, sizeof(addr));
   406         -      memset(&scope, 0, sizeof(scope));
   407         -      IN6ADDR_SETV4MAPPED(&addr, &in4addr_loopback, scope, htons(iPort));
          403  +      ((SOCKADDR_IN6*)&addr)->sin6_port = htons(iPort);
          404  +      fossil_free(zIp);
   408    405       }else{
   409         -      memset(&addr, 0, sizeof(addr));
   410    406         addr.sin6_family = AF_INET6;
   411    407         addr.sin6_port = htons(iPort);
   412    408         memcpy(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any));
   413    409       }
   414    410       if( bind(s, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR ){
   415    411         closesocket(s);
   416    412         iPort++;