Ok, heres a patch attached.

The patch will use ipv6 socket instead of ipv4. The socketoption
IPV6_V6ONLY is explicitly disabled, allowing incomming ipv4 connections to
be accepted as well.

Caveats:
1. The part on invoking a cgi-server with the zIpAddr parameter specified
is not tested, since I cannot figure out when this is used. However, it
zIpAddr is an ipv4 string (e.g. 127.0.0.1) it will be converted to mixed
notation ::FFFF:127.0.0.1 and then used as ipv6 address.
2. The "fossil ui" command stumbles about this, cause ipv6 stack can accept
connection froms ipv4 adresses, but ipv6-loopback does only accept
incomming connections to [::1] but not to "localhost". To accept urls with
"localhost" a second socket for ipv4-loopback would be needed - at least
thats written on the internet. I think I'll  have to do an check on what
can be used to open the browser correctly.

As I'm completly new to c programming this is more a draft than anything I
would call a contribution, but for "fossil server" it works already and
I'll definetly spend more time on that next week.

Richard Hipp <d...@sqlite.org> schrieb am Do., 2. Apr. 2015 um 15:13 Uhr:

> On 4/2/15, Oliver Friedrich <redtalonof+mailingl...@gmail.com> wrote:
> > Ah, ok. Accessing the web interface via ipv6 would be useful now, but
> what
> > has to wait, has to wait.
>
> You could work on a patch while you are waiting :-)
>
> --
> D. Richard Hipp
> d...@sqlite.org
> _______________________________________________
> fossil-users mailing list
> fossil-users@lists.fossil-scm.org
> http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users
>
Index: src/cgi.c
==================================================================
--- src/cgi.c
+++ src/cgi.c
@@ -1305,36 +1305,48 @@
   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() */
-  struct sockaddr_in inaddr;   /* The socket address */
-  int opt = 1;                 /* setsockopt flag */
+  struct sockaddr_in6 inaddr;   /* The socket address */
+  int optyes = 1;                 /* setsockopt flag */
+  int optno = 0;                 /* setsockopt flag */
   int iPort = mnPort;
+  char ip[INET6_ADDRSTRLEN];
+  
 
   while( iPort<=mxPort ){
     memset(&inaddr, 0, sizeof(inaddr));
-    inaddr.sin_family = AF_INET;
+    inaddr.sin6_family = AF_INET6;
     if( zIpAddr ){
-      inaddr.sin_addr.s_addr = inet_addr(zIpAddr);
-      if( inaddr.sin_addr.s_addr == (-1) ){
-        fossil_fatal("not a valid IP address: %s", zIpAddr);
+        printf("zIpAddr: %s", zIpAddr);
+        /* check valid ipv6 address */
+      if (inet_pton(AF_INET6, zIpAddr, &inaddr) == -1){
+          /* maybe ipv4 string so try mixed ipv4 notation*/
+          strcpy(ip, "::FFFF:");
+          strcat(ip, zIpAddr);
+          printf("zIpAddr: %s", ip);
+          if (inet_pton(AF_INET6, ip, &inaddr) == -1){
+            fossil_fatal("not a valid IP address: %s", zIpAddr);
+          }
       }
     }else if( flags & HTTP_SERVER_LOCALHOST ){
-      inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+      inaddr.sin6_addr = in6addr_loopback;
     }else{
-      inaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+      inaddr.sin6_addr = in6addr_any;
     }
-    inaddr.sin_port = htons(iPort);
-    listener = socket(AF_INET, SOCK_STREAM, 0);
+    inaddr.sin6_port = htons(iPort);
+    listener = socket(AF_INET6, SOCK_STREAM, 0);
     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));
+    setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &optyes, sizeof(optyes));
+    /* explicitly disable IPV6ONLY option for dualstack usage */
+    setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &optno, sizeof(optno));
 
     if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){
       close(listener);
       iPort++;
       continue;

Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -1850,11 +1850,12 @@
     zBrowser = db_get("web-browser", "open");
 #endif
     if( zIpAddr ){
       zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr);
     }else{
-      zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);
+      /*zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser);*/
+      zBrowserCmd = mprintf("%s http://[::1]:%%d/ &", zBrowser);
     }
   }
   db_close(1);
   if( cgi_http_server(iPort, mxPort, zBrowserCmd, zIpAddr, flags) ){
     fossil_fatal("unable to listen on TCP socket %d", iPort);

_______________________________________________
fossil-users mailing list
fossil-users@lists.fossil-scm.org
http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users

Reply via email to