Fossil SCM
Enable the use of IPv6 for "fossil ui" and "fossil server" on unix.
Commit
dae37f0e358368017ebea223f604b379ab7055d3
Parent
5a12e8c3b68fc90…
2 files changed
+24
-11
+1
-1
+24
-11
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1718,36 +1718,49 @@ | ||
| 1718 | 1718 | fd_set readfds; /* Set of file descriptors for select() */ |
| 1719 | 1719 | socklen_t lenaddr; /* Length of the inaddr structure */ |
| 1720 | 1720 | int child; /* PID of the child process */ |
| 1721 | 1721 | int nchildren = 0; /* Number of child processes */ |
| 1722 | 1722 | struct timeval delay; /* How long to wait inside select() */ |
| 1723 | - struct sockaddr_in inaddr; /* The socket address */ | |
| 1724 | - int opt = 1; /* setsockopt flag */ | |
| 1723 | + struct sockaddr_in6 inaddr; /* The socket address */ | |
| 1724 | + int optyes = 1; /* setsockopt flag */ | |
| 1725 | + int optno = 0; /* setsockopt flag */ | |
| 1725 | 1726 | int iPort = mnPort; |
| 1727 | + char ip[INET6_ADDRSTRLEN]; | |
| 1728 | + | |
| 1726 | 1729 | |
| 1727 | 1730 | while( iPort<=mxPort ){ |
| 1728 | 1731 | memset(&inaddr, 0, sizeof(inaddr)); |
| 1729 | - inaddr.sin_family = AF_INET; | |
| 1732 | + inaddr.sin6_family = AF_INET6; | |
| 1730 | 1733 | if( zIpAddr ){ |
| 1731 | - inaddr.sin_addr.s_addr = inet_addr(zIpAddr); | |
| 1732 | - if( inaddr.sin_addr.s_addr == (-1) ){ | |
| 1733 | - fossil_fatal("not a valid IP address: %s", zIpAddr); | |
| 1734 | + printf("zIpAddr: %s", zIpAddr); | |
| 1735 | + printf("iPort: %d", iPort); | |
| 1736 | + /* check valid ipv6 address */ | |
| 1737 | + if (inet_pton(AF_INET6, zIpAddr, &(inaddr.sin6_addr)) < 1) { | |
| 1738 | + /* maybe ipv4 string so try mixed ipv4 notation*/ | |
| 1739 | + strcpy(ip, "::FFFF:"); | |
| 1740 | + strcat(ip, zIpAddr); | |
| 1741 | + printf("zIpAddr: %s", ip); | |
| 1742 | + if (inet_pton(AF_INET6, ip, &(inaddr.sin6_addr)) == -1){ | |
| 1743 | + fossil_fatal("not a valid IP address: %s", zIpAddr); | |
| 1744 | + } | |
| 1734 | 1745 | } |
| 1735 | 1746 | }else if( flags & HTTP_SERVER_LOCALHOST ){ |
| 1736 | - inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
| 1747 | + inaddr.sin6_addr = in6addr_loopback; | |
| 1737 | 1748 | }else{ |
| 1738 | - inaddr.sin_addr.s_addr = htonl(INADDR_ANY); | |
| 1749 | + inaddr.sin6_addr = in6addr_any; | |
| 1739 | 1750 | } |
| 1740 | - inaddr.sin_port = htons(iPort); | |
| 1741 | - listener = socket(AF_INET, SOCK_STREAM, 0); | |
| 1751 | + inaddr.sin6_port = htons(iPort); | |
| 1752 | + listener = socket(AF_INET6, SOCK_STREAM, 0); | |
| 1742 | 1753 | if( listener<0 ){ |
| 1743 | 1754 | iPort++; |
| 1744 | 1755 | continue; |
| 1745 | 1756 | } |
| 1746 | 1757 | |
| 1747 | 1758 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 1748 | - setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); | |
| 1759 | + setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &optyes, sizeof(optyes)); | |
| 1760 | + /* explicitly disable IPV6ONLY option for dualstack usage */ | |
| 1761 | + setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &optno, sizeof(optno)); | |
| 1749 | 1762 | |
| 1750 | 1763 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1751 | 1764 | close(listener); |
| 1752 | 1765 | iPort++; |
| 1753 | 1766 | continue; |
| 1754 | 1767 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1718,36 +1718,49 @@ | |
| 1718 | fd_set readfds; /* Set of file descriptors for select() */ |
| 1719 | socklen_t lenaddr; /* Length of the inaddr structure */ |
| 1720 | int child; /* PID of the child process */ |
| 1721 | int nchildren = 0; /* Number of child processes */ |
| 1722 | struct timeval delay; /* How long to wait inside select() */ |
| 1723 | struct sockaddr_in inaddr; /* The socket address */ |
| 1724 | int opt = 1; /* setsockopt flag */ |
| 1725 | int iPort = mnPort; |
| 1726 | |
| 1727 | while( iPort<=mxPort ){ |
| 1728 | memset(&inaddr, 0, sizeof(inaddr)); |
| 1729 | inaddr.sin_family = AF_INET; |
| 1730 | if( zIpAddr ){ |
| 1731 | inaddr.sin_addr.s_addr = inet_addr(zIpAddr); |
| 1732 | if( inaddr.sin_addr.s_addr == (-1) ){ |
| 1733 | fossil_fatal("not a valid IP address: %s", zIpAddr); |
| 1734 | } |
| 1735 | }else if( flags & HTTP_SERVER_LOCALHOST ){ |
| 1736 | inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
| 1737 | }else{ |
| 1738 | inaddr.sin_addr.s_addr = htonl(INADDR_ANY); |
| 1739 | } |
| 1740 | inaddr.sin_port = htons(iPort); |
| 1741 | listener = socket(AF_INET, SOCK_STREAM, 0); |
| 1742 | if( listener<0 ){ |
| 1743 | iPort++; |
| 1744 | continue; |
| 1745 | } |
| 1746 | |
| 1747 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 1748 | setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); |
| 1749 | |
| 1750 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1751 | close(listener); |
| 1752 | iPort++; |
| 1753 | continue; |
| 1754 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1718,36 +1718,49 @@ | |
| 1718 | fd_set readfds; /* Set of file descriptors for select() */ |
| 1719 | socklen_t lenaddr; /* Length of the inaddr structure */ |
| 1720 | int child; /* PID of the child process */ |
| 1721 | int nchildren = 0; /* Number of child processes */ |
| 1722 | struct timeval delay; /* How long to wait inside select() */ |
| 1723 | struct sockaddr_in6 inaddr; /* The socket address */ |
| 1724 | int optyes = 1; /* setsockopt flag */ |
| 1725 | int optno = 0; /* setsockopt flag */ |
| 1726 | int iPort = mnPort; |
| 1727 | char ip[INET6_ADDRSTRLEN]; |
| 1728 | |
| 1729 | |
| 1730 | while( iPort<=mxPort ){ |
| 1731 | memset(&inaddr, 0, sizeof(inaddr)); |
| 1732 | inaddr.sin6_family = AF_INET6; |
| 1733 | if( zIpAddr ){ |
| 1734 | printf("zIpAddr: %s", zIpAddr); |
| 1735 | printf("iPort: %d", iPort); |
| 1736 | /* check valid ipv6 address */ |
| 1737 | if (inet_pton(AF_INET6, zIpAddr, &(inaddr.sin6_addr)) < 1) { |
| 1738 | /* maybe ipv4 string so try mixed ipv4 notation*/ |
| 1739 | strcpy(ip, "::FFFF:"); |
| 1740 | strcat(ip, zIpAddr); |
| 1741 | printf("zIpAddr: %s", ip); |
| 1742 | if (inet_pton(AF_INET6, ip, &(inaddr.sin6_addr)) == -1){ |
| 1743 | fossil_fatal("not a valid IP address: %s", zIpAddr); |
| 1744 | } |
| 1745 | } |
| 1746 | }else if( flags & HTTP_SERVER_LOCALHOST ){ |
| 1747 | inaddr.sin6_addr = in6addr_loopback; |
| 1748 | }else{ |
| 1749 | inaddr.sin6_addr = in6addr_any; |
| 1750 | } |
| 1751 | inaddr.sin6_port = htons(iPort); |
| 1752 | listener = socket(AF_INET6, SOCK_STREAM, 0); |
| 1753 | if( listener<0 ){ |
| 1754 | iPort++; |
| 1755 | continue; |
| 1756 | } |
| 1757 | |
| 1758 | /* if we can't terminate nicely, at least allow the socket to be reused */ |
| 1759 | setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &optyes, sizeof(optyes)); |
| 1760 | /* explicitly disable IPV6ONLY option for dualstack usage */ |
| 1761 | setsockopt(listener, IPPROTO_IPV6, IPV6_V6ONLY, &optno, sizeof(optno)); |
| 1762 | |
| 1763 | if( bind(listener, (struct sockaddr*)&inaddr, sizeof(inaddr))<0 ){ |
| 1764 | close(listener); |
| 1765 | iPort++; |
| 1766 | continue; |
| 1767 |
+1
-1
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -2416,11 +2416,11 @@ | ||
| 2416 | 2416 | zBrowser = db_get("web-browser", "open"); |
| 2417 | 2417 | #endif |
| 2418 | 2418 | if( zIpAddr ){ |
| 2419 | 2419 | zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr); |
| 2420 | 2420 | }else{ |
| 2421 | - zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); | |
| 2421 | + zBrowserCmd = mprintf("%s http://[::1]:%%d/ &", zBrowser); | |
| 2422 | 2422 | } |
| 2423 | 2423 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2424 | 2424 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2425 | 2425 | } |
| 2426 | 2426 | db_close(1); |
| 2427 | 2427 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2416,11 +2416,11 @@ | |
| 2416 | zBrowser = db_get("web-browser", "open"); |
| 2417 | #endif |
| 2418 | if( zIpAddr ){ |
| 2419 | zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr); |
| 2420 | }else{ |
| 2421 | zBrowserCmd = mprintf("%s http://localhost:%%d/ &", zBrowser); |
| 2422 | } |
| 2423 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2424 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2425 | } |
| 2426 | db_close(1); |
| 2427 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -2416,11 +2416,11 @@ | |
| 2416 | zBrowser = db_get("web-browser", "open"); |
| 2417 | #endif |
| 2418 | if( zIpAddr ){ |
| 2419 | zBrowserCmd = mprintf("%s http://%s:%%d/ &", zBrowser, zIpAddr); |
| 2420 | }else{ |
| 2421 | zBrowserCmd = mprintf("%s http://[::1]:%%d/ &", zBrowser); |
| 2422 | } |
| 2423 | if( g.repositoryOpen ) flags |= HTTP_SERVER_HAD_REPOSITORY; |
| 2424 | if( g.localOpen ) flags |= HTTP_SERVER_HAD_CHECKOUT; |
| 2425 | } |
| 2426 | db_close(1); |
| 2427 |