Portability fixes for Mingw33
[freeradius.git] / src / main / listen.c
index 273634d..dd87af6 100644 (file)
@@ -318,7 +318,7 @@ static int listen_bind(rad_listen_t *this);
  *     Like rad_authenticate and rad_accounting this should
  *     live in it's own file but it's so small we don't bother.
  */
-static int rad_status_server(REQUEST *request)
+int rad_status_server(REQUEST *request)
 {
        int rcode = RLM_MODULE_OK;
        DICT_VALUE *dval;
@@ -550,7 +550,7 @@ static int dual_tcp_accept(rad_listen_t *listener)
        struct sockaddr_storage src;
        listen_socket_t *sock;
        fr_ipaddr_t src_ipaddr;
-       RADCLIENT *client;
+       RADCLIENT *client = NULL;
        
        salen = sizeof(src);
 
@@ -561,9 +561,11 @@ static int dual_tcp_accept(rad_listen_t *listener)
                /*
                 *      Non-blocking sockets must handle this.
                 */
+#ifdef EWOULDBLOCK
                if (errno == EWOULDBLOCK) {
                        return 0;
                }
+#endif
 
                DEBUG2(" ... failed to accept connection.");
                return -1;
@@ -631,11 +633,19 @@ static int dual_tcp_accept(rad_listen_t *listener)
        sock->other_ipaddr = src_ipaddr;
        sock->other_port = src_port;
        sock->client = client;
+       sock->opened = sock->last_packet = time(NULL);
 
        this->fd = newfd;
        this->status = RAD_LISTEN_STATUS_INIT;
        this->recv = dual_tcp_recv;
 
+#ifdef WITH_TLS
+       if (this->tls) {
+               this->recv = dual_tls_recv;
+               this->send = dual_tls_send;
+       }
+#endif
+
        /*
         *      FIXME: set O_NONBLOCK on the accept'd fd.
         *      See djb's portability rants for details.
@@ -750,11 +760,6 @@ static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
                snprintf(buffer, bufsize, "%d", sock->my_port);
                FORWARD;
 
-               if (this->tls) {
-                       ADDSTRING(" (TLS)");
-                       FORWARD;
-               }
-
                if (this->server) {
                        ADDSTRING(", virtual-server=");
                        ADDSTRING(this->server);
@@ -813,6 +818,13 @@ static int socket_print(const rad_listen_t *this, char *buffer, size_t bufsize)
        snprintf(buffer, bufsize, "%d", sock->my_port);
        FORWARD;
 
+#ifdef WITH_TLS
+       if (this->tls) {
+               ADDSTRING(" (TLS)");
+               FORWARD;
+       }
+#endif
+
        if (this->server) {
                ADDSTRING(" as server ");
                ADDSTRING(this->server);
@@ -844,6 +856,7 @@ static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
        /*
         *      Try IPv4 first
         */
+       memset(&ipaddr, 0, sizeof(ipaddr));
        ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);
        rcode = cf_item_parse(cs, "ipaddr", PW_TYPE_IPADDR,
                              &ipaddr.ipaddr.ip4addr, NULL);
@@ -1195,7 +1208,7 @@ static int proxy_socket_send(rad_listen_t *listener, REQUEST *request)
        rad_assert(request->proxy_listener == listener);
        rad_assert(listener->send == proxy_socket_send);
 
-       if (rad_send(request->proxy, request->packet,
+       if (rad_send(request->proxy, NULL,
                     request->home_server->secret) < 0) {
                radlog_request(L_ERR, 0, request, "Failed sending proxied request: %s",
                               fr_strerror());
@@ -1218,7 +1231,7 @@ static int stats_socket_recv(rad_listen_t *listener)
        ssize_t         rcode;
        int             code, src_port;
        RADIUS_PACKET   *packet;
-       RADCLIENT       *client;
+       RADCLIENT       *client = NULL;
        fr_ipaddr_t     src_ipaddr;
 
        rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
@@ -1238,7 +1251,7 @@ static int stats_socket_recv(rad_listen_t *listener)
                return 0;
        }
 
-       FR_STATS_TYPE_INC(client->auth->total_requests);
+       FR_STATS_TYPE_INC(client->auth.total_requests);
 
        /*
         *      We only understand Status-Server on this socket.
@@ -1285,7 +1298,7 @@ static int auth_socket_recv(rad_listen_t *listener)
        int             code, src_port;
        RADIUS_PACKET   *packet;
        RAD_REQUEST_FUNP fun = NULL;
-       RADCLIENT       *client;
+       RADCLIENT       *client = NULL;
        fr_ipaddr_t     src_ipaddr;
 
        rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
@@ -1305,7 +1318,7 @@ static int auth_socket_recv(rad_listen_t *listener)
                return 0;
        }
 
-       FR_STATS_TYPE_INC(client->auth->total_requests);
+       FR_STATS_TYPE_INC(client->auth.total_requests);
 
        /*
         *      Some sanity checks, based on the packet code.
@@ -1366,7 +1379,7 @@ static int acct_socket_recv(rad_listen_t *listener)
        int             code, src_port;
        RADIUS_PACKET   *packet;
        RAD_REQUEST_FUNP fun = NULL;
-       RADCLIENT       *client;
+       RADCLIENT       *client = NULL;
        fr_ipaddr_t     src_ipaddr;
 
        rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
@@ -1386,7 +1399,7 @@ static int acct_socket_recv(rad_listen_t *listener)
                return 0;
        }
 
-       FR_STATS_TYPE_INC(client->acct->total_requests);
+       FR_STATS_TYPE_INC(client->acct.total_requests);
 
        /*
         *      Some sanity checks, based on the packet code.
@@ -1615,7 +1628,7 @@ static int coa_socket_recv(rad_listen_t *listener)
        int             code, src_port;
        RADIUS_PACKET   *packet;
        RAD_REQUEST_FUNP fun = NULL;
-       RADCLIENT       *client;
+       RADCLIENT       *client = NULL;
        fr_ipaddr_t     src_ipaddr;
 
        rcode = rad_recv_header(listener->fd, &src_ipaddr, &src_port, &code);
@@ -2029,6 +2042,14 @@ static int listen_bind(rad_listen_t *this)
        }
 
        /*
+        *      Don't open sockets if we're checking the config.
+        */
+       if (check_config) {
+               this->fd = -1;
+               return 0;
+       }
+
+       /*
         *      Copy fr_socket() here, as we may need to bind to a device.
         */
        this->fd = socket(sock->my_ipaddr.af, sock_type, 0);
@@ -2047,7 +2068,9 @@ static int listen_bind(rad_listen_t *this)
        if (sock->interface) {
 #ifdef SO_BINDTODEVICE
                struct ifreq ifreq;
-               strcpy(ifreq.ifr_name, sock->interface);
+
+               memset(&ifreq, 0, sizeof(ifreq));
+               strlcpy(ifreq.ifr_name, sock->interface, sizeof(ifreq.ifr_name));
 
                fr_suid_up();
                rcode = setsockopt(this->fd, SOL_SOCKET, SO_BINDTODEVICE,
@@ -2352,6 +2375,9 @@ int proxy_new_listener(home_server *home, int src_port)
 {
        rad_listen_t *this;
        listen_socket_t *sock;
+#ifndef NDEBUG
+       char buffer[256];
+#endif
 
        if (!home) return 0;
 
@@ -2373,8 +2399,13 @@ int proxy_new_listener(home_server *home, int src_port)
        sock->my_port = src_port;
        sock->proto = home->proto;
 
+       if (debug_flag >= 2) {
+               this->print(this, buffer, sizeof(buffer));
+               DEBUG("Opening new %s", buffer);
+       }
+
 #ifdef WITH_TCP
-       sock->last_packet = time(NULL);
+       sock->opened = sock->last_packet = time(NULL);
 
        if (home->proto == IPPROTO_TCP) {
                this->recv = proxy_socket_tcp_recv;
@@ -2388,12 +2419,27 @@ int proxy_new_listener(home_server *home, int src_port)
                 */
                this->fd = fr_tcp_client_socket(&home->src_ipaddr,
                                                &home->ipaddr, home->port);
+#ifdef WITH_TLS
+               if (home->tls) {
+                       DEBUG("Trying SSL to port %d\n", home->port);
+                       sock->ssn = tls_new_client_session(home->tls, this->fd);
+                       if (!sock->ssn) {
+                               listen_free(&this);
+                               return 0;
+                       }
+
+                       this->recv = proxy_tls_recv;
+                       this->send = proxy_tls_send;
+               }
+#endif
        } else
 #endif
                this->fd = fr_socket(&home->src_ipaddr, src_port);
 
        if (this->fd < 0) {
-               DEBUG("Failed opening client socket: %s", fr_strerror());
+               this->print(this, buffer,sizeof(buffer));
+               DEBUG("Failed opening client socket ::%s:: : %s",
+                     buffer, fr_strerror());
                listen_free(&this);
                return 0;
        }
@@ -2579,6 +2625,9 @@ int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
 #ifdef WITH_PROXY
        int             defined_proxy = 0;
 #endif
+#ifndef WITH_TLS
+       spawn_flag = spawn_flag; /* -Wunused */
+#endif
 
        /*
         *      We shouldn't be called with a pre-existing list.
@@ -2657,15 +2706,6 @@ int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
                        if (cs) this->server = mainconfig.name;
                }
 
-#ifdef WITH_TLS
-               if (!spawn_flag && this->tls) {
-               tls_error:
-                       cf_log_err(cf_sectiontoitem(cs), "Threading must be enabled for TLS sockets to function properly.");
-                       listen_free(&this);
-                       return -1;
-               }
-#endif
-
                *last = this;
                last = &(this->next);
 
@@ -2748,10 +2788,6 @@ int listen_init(CONF_SECTION *config, rad_listen_t **head, int spawn_flag)
                                return -1;
                        }
 
-#ifdef WITH_TLS
-                       if (!spawn_flag && this->tls) goto tls_error;
-#endif
-
                        *last = this;
                        last = &(this->next);
                } /* loop over "listen" directives in server <foo> */
@@ -2821,7 +2857,15 @@ add_sockets:
                }
 
 #endif
-               event_new_fd(this);
+
+#ifdef WITH_TLS
+               if (!spawn_flag && this->tls) {
+                       cf_log_err(cf_sectiontoitem(this->cs), "Threading must be enabled for TLS sockets to function properly.");
+                       cf_log_err(cf_sectiontoitem(this->cs), "You probably need to do 'radiusd -fxx -l stdout' for debugging");
+                       return -1;
+               }
+#endif
+               if (!check_config) event_new_fd(this);
        }
 
        /*
@@ -2830,6 +2874,7 @@ add_sockets:
         */
 #ifdef WITH_PROXY
        if ((mainconfig.proxy_requests == TRUE) &&
+           !check_config &&
            (*head != NULL) && !defined_proxy) {
                listen_socket_t *sock = NULL;
                int             port = 0;