Unix domain sockets don't work well in non-blocking.
[citadel.git] / webcit / tcp_sockets.c
index 2835344f47eef51393adcfdc1ef66714ec07cc42..f1bcd5bc096d75bb2e5dbe80990d1de377d33c8f 100644 (file)
@@ -53,7 +53,6 @@ int uds_connectsock(char *sockpath)
                close(s);
                return(-1);
        }
-
        return s;
 }
 
@@ -123,7 +122,28 @@ int tcp_connectsock(char *host, char *service)
                }
                rc = connect(s, ai->ai_addr, ai->ai_addrlen);
                if (rc >= 0) {
+                       int fdflags;
                        freeaddrinfo(res);
+
+                       fdflags = fcntl(rc, F_GETFL);
+                       if (fdflags < 0) {
+                               syslog(LOG_ERR,
+                                      "unable to get socket %d flags! %s \n",
+                                      rc,
+                                      strerror(errno));
+                               close(rc);
+                               return -1;
+                       }
+                       fdflags = fdflags | O_NONBLOCK;
+                       if (fcntl(rc, F_SETFL, fdflags) < 0) {
+                               syslog(LOG_ERR,
+                                      "unable to set socket %d nonblocking flags! %s \n",
+                                      rc,
+                                      strerror(errno));
+                               close(s);
+                               return -1;
+                       }
+
                        return(s);
                }
                else {
@@ -153,7 +173,7 @@ int serv_getln(char *strbuf, int bufsize)
        FlushStrBuf(WCC->MigrateReadLineBuf);
        strbuf[len] = '\0';
 #ifdef SERV_TRACE
-       syslog(LOG_DEBUG, "%3d<<<%s\n", WC->serv_sock, strbuf);
+       syslog(LOG_DEBUG, "%3d<<<%s\n", WCC->serv_sock, strbuf);
 #endif
        return len;
 }
@@ -512,14 +532,17 @@ int ClientGetLine(ParsedHttpHdrs *Hdr, StrBuf *Target)
  * port_number port number to bind
  * queue_len   number of incoming connections to allow in the queue
  */
-int webcit_tcp_server(char *ip_addr, int port_number, int queue_len)
+int webcit_tcp_server(const char *ip_addr, int port_number, int queue_len)
 {
+       const char *ipv4broadcast = "0.0.0.0";
+       int IsDefault = 0;
        struct protoent *p;
        struct sockaddr_in6 sin6;
        struct sockaddr_in sin4;
        int s, i, b;
        int ip_version = 6;
 
+retry:
        memset(&sin6, 0, sizeof(sin6));
        memset(&sin4, 0, sizeof(sin4));
        sin6.sin6_family = AF_INET6;
@@ -529,6 +552,7 @@ int webcit_tcp_server(char *ip_addr, int port_number, int queue_len)
                || (IsEmptyStr(ip_addr))
                || (!strcmp(ip_addr, "*"))
        ) {
+               IsDefault = 1;
                ip_version = 6;
                sin6.sin6_addr = in6addr_any;
        }
@@ -565,6 +589,12 @@ int webcit_tcp_server(char *ip_addr, int port_number, int queue_len)
 
        s = socket( ((ip_version == 6) ? PF_INET6 : PF_INET), SOCK_STREAM, (p->p_proto));
        if (s < 0) {
+               if (IsDefault && (errno == EAFNOSUPPORT))
+               {
+                       s = 0;
+                       ip_addr = ipv4broadcast;
+                       goto retry;
+               }
                syslog(LOG_WARNING, "Can't create a listening socket: %s\n", strerror(errno));
                return (-WC_EXIT_BIND);
        }