Portability fixes for Mingw33
[freeradius.git] / src / main / listen.c
index 39913c2..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;
@@ -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.
@@ -808,10 +818,12 @@ 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 ");
@@ -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());
@@ -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.
@@ -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.
@@ -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.
@@ -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,
@@ -2396,6 +2419,19 @@ 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);
@@ -2589,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.
@@ -2667,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);
 
@@ -2758,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> */
@@ -2831,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);
        }
 
        /*
@@ -2840,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;