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