Include proto in API, no matter what build options
authorAlan T. DeKok <aland@freeradius.org>
Sun, 27 Sep 2009 16:23:18 +0000 (18:23 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 27 Sep 2009 16:23:18 +0000 (18:23 +0200)
It's too hardware to have proto as a compile-time option
for the API.  Instead, we add it everywhere.  This slows down the
UDP-only case, but ensures that we can distinguish between a
home server of (ip,port) udp, and a home server of the same (ip,port)
and tcp

src/include/packet.h
src/include/radiusd.h
src/include/realms.h
src/lib/packet.c
src/main/client.c
src/main/command.c
src/main/event.c
src/main/listen.c
src/main/realms.c

index f00eb90..a700541 100644 (file)
@@ -50,11 +50,11 @@ RADIUS_PACKET **fr_packet_list_find_byreply(fr_packet_list_t *pl,
 RADIUS_PACKET **fr_packet_list_yank(fr_packet_list_t *pl,
                                      RADIUS_PACKET *request);
 int fr_packet_list_num_elements(fr_packet_list_t *pl);
-int fr_packet_list_id_alloc(fr_packet_list_t *pl,
+int fr_packet_list_id_alloc(fr_packet_list_t *pl, int proto,
                            RADIUS_PACKET *request, void **pctx);
 int fr_packet_list_id_free(fr_packet_list_t *pl,
                             RADIUS_PACKET *request);
-int fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd,
+int fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd, int proto,
                              fr_ipaddr_t *dst_ipaddr, int dst_port,
                              void *ctx);
 int fr_packet_list_socket_remove(fr_packet_list_t *pl, int sockfd,
index 9d77595..f5b295e 100644 (file)
@@ -128,8 +128,8 @@ typedef struct radclient {
 #endif
 #endif
 
-#ifdef WITH_TCP
        int                     proto;
+#ifdef WITH_TCP
        int                     max_connections;
        int                     num_connections;
 #endif
@@ -354,9 +354,9 @@ typedef struct listen_socket_t {
        fr_ipaddr_t     other_ipaddr;
        int             other_port;
 
-#ifdef WITH_TCP
        int             proto;
 
+#ifdef WITH_TCP
        /* for a proxy connecting to home servers */
        time_t          last_packet;
        time_t          opened;
@@ -560,11 +560,8 @@ void               client_delete(RADCLIENT_LIST *clients, RADCLIENT *client);
 RADCLIENT      *client_create(RADCLIENT_LIST *clients, REQUEST *request);
 #endif
 RADCLIENT      *client_find(const RADCLIENT_LIST *clients,
-                            const fr_ipaddr_t *ipaddr
-#ifdef WITH_TCP
-                            , int proto
-#endif
-);
+                            const fr_ipaddr_t *ipaddr, int proto);
+
 RADCLIENT      *client_findbynumber(const RADCLIENT_LIST *clients,
                                     int number);
 RADCLIENT      *client_find_old(const fr_ipaddr_t *ipaddr);
index c4d6891..1467b2b 100644 (file)
@@ -38,9 +38,7 @@ typedef struct home_server {
        int             port;
        int             type;           /* auth/acct */
 
-#ifdef WITH_TCP
        int             proto;
-#endif
        int             max_connections;
        int             num_connections; /* protected by proxy mutex */
        int             max_requests;    /* for one connection */
index d85d598..ffad9d9 100644 (file)
@@ -323,7 +323,7 @@ typedef struct fr_packet_socket_t {
        int             dont_use;
 
 #ifdef WITH_TCP
-       int             type;
+       int             proto;
 #endif
 
        uint8_t         id[32];
@@ -405,7 +405,7 @@ int fr_packet_list_socket_remove(fr_packet_list_t *pl, int sockfd,
        return 1;
 }
 
-int fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd,
+int fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd, int proto,
                              fr_ipaddr_t *dst_ipaddr, int dst_port,
                              void *ctx)
 {
@@ -439,16 +439,7 @@ int fr_packet_list_socket_add(fr_packet_list_t *pl, int sockfd,
 
        memset(ps, 0, sizeof(*ps));
        ps->ctx = ctx;
-
-#ifdef WITH_TCP
-       sizeof_src = sizeof(ps->type);
-
-       if (getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &ps->type, &sizeof_src) < 0) {
-               fr_strerror_printf("%s", strerror(errno));
-               return 0;
-       }
-
-#endif
+       ps->proto = proto;
 
        /*
         *      Get address family, etc. first, so we know if we
@@ -640,7 +631,7 @@ int fr_packet_list_num_elements(fr_packet_list_t *pl)
  *     We also assume that the sender doesn't care which protocol
  *     should be used.
  */
-int fr_packet_list_id_alloc(fr_packet_list_t *pl,
+int fr_packet_list_id_alloc(fr_packet_list_t *pl, int proto,
                            RADIUS_PACKET *request, void **pctx)
 {
        int i, j, k, fd, id, start_i, start_j, start_k;
@@ -653,6 +644,13 @@ int fr_packet_list_id_alloc(fr_packet_list_t *pl,
                return 0;
        }
 
+#ifndef WITH_TCP
+       if ((proto != 0) && (proto != IPPROTO_UDP)) {
+               fr_strerror_printf("Invalid destination protocol");
+               return 0;
+       }
+#endif
+
        /*
         *      Special case: unspec == "don't care"
         */
@@ -710,13 +708,23 @@ int fr_packet_list_id_alloc(fr_packet_list_t *pl,
                 */
                if (ps->num_outgoing == 256) continue;
 
+#ifdef WITH_TCP
+               if (ps->proto != proto) continue;
+#endif
+
                /*
-                *      MUST match dst port, if one has been given.
+                *      MUST match dst port, if we have one.
                 */
                if ((ps->dst_port != 0) && 
                    (ps->dst_port != request->dst_port)) continue;
 
                /*
+                *      MUST match requested src port, if one has been given.
+                */
+               if ((request->src_port != 0) && 
+                   (ps->dst_port != request->dst_port)) continue;
+
+               /*
                 *      We're sourcing from *, and they asked for a
                 *      specific source address: ignore it.
                 */
@@ -880,7 +888,7 @@ RADIUS_PACKET *fr_packet_list_recv(fr_packet_list_t *pl, fd_set *set)
                if (!FD_ISSET(pl->sockets[start].sockfd, set)) continue;
 
 #ifdef WITH_TCP
-               if (pl->sockets[start].type == SOCK_STREAM) {
+               if (pl->sockets[start].proto == IPPROTO_TCP) {
                        packet = fr_tcp_recv(pl->sockets[start].sockfd, 0);
                } else
 #endif
index 7b1c7c7..247ce1d 100644 (file)
@@ -376,11 +376,7 @@ int client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
                 *      If there IS an enclosing network,
                 *      inherit the lifetime from it.
                 */
-               network = client_find(clients, &client->ipaddr
-#ifdef WITH_TCP
-                                     , client->proto
-#endif
-                       );
+               network = client_find(clients, &client->ipaddr, client->proto);
                if (network) {
                        client->lifetime = network->lifetime;
                }
@@ -448,11 +444,7 @@ RADCLIENT *client_findbynumber(const RADCLIENT_LIST *clients,
  *     Find a client in the RADCLIENTS list.
  */
 RADCLIENT *client_find(const RADCLIENT_LIST *clients,
-                      const fr_ipaddr_t *ipaddr
-#ifdef WITH_TCP
-                      , int proto
-#endif
-       )
+                      const fr_ipaddr_t *ipaddr, int proto)
 {
        int i, max_prefix;
        RADCLIENT myclient;
@@ -479,9 +471,7 @@ RADCLIENT *client_find(const RADCLIENT_LIST *clients,
 
                myclient.prefix = i;
                myclient.ipaddr = *ipaddr;
-#ifdef WITH_TCP
                myclient.proto = proto;
-#endif
                client_sane(&myclient); /* clean up the ipaddress */
 
                if (!clients->trees[i]) continue;
@@ -698,8 +688,8 @@ static RADCLIENT *client_parse(CONF_SECTION *cs, int in_server)
                 */
                if (!c->shortname) c->shortname = strdup(name2);
 
-#ifdef WITH_TCP
                c->proto = IPPROTO_UDP;
+#ifdef WITH_TCP
                if (hs_proto) {
                        if (strcmp(hs_proto, "udp") == 0) {
                                free(hs_proto);
index 4943b34..1489fb6 100644 (file)
@@ -802,10 +802,7 @@ static RADCLIENT *get_client(rad_listen_t *listener, int argc, char *argv[])
 {
        RADCLIENT *client;
        fr_ipaddr_t ipaddr;
-
-#ifdef WITH_TCP
        int proto = IPPROTO_UDP;
-#endif
 
        if (argc < 1) {
                cprintf(listener, "ERROR: Must specify <ipaddr>\n");
@@ -834,11 +831,7 @@ static RADCLIENT *get_client(rad_listen_t *listener, int argc, char *argv[])
        }
 #endif
 
-       client = client_find(NULL, &ipaddr
-#ifdef WITH_TCP
-                            , proto
-#endif
-               );
+       client = client_find(NULL, &ipaddr, proto);
        if (!client) {
                cprintf(listener, "ERROR: No such client\n");
                return NULL;
index f92243e..dbb7f66 100644 (file)
@@ -369,8 +369,8 @@ static int proxy_id_alloc(REQUEST *request, RADIUS_PACKET *packet)
 {
        void *proxy_listener;
 
-       if (fr_packet_list_id_alloc(proxy_list, packet,
-                                   &proxy_listener)) {
+       if (fr_packet_list_id_alloc(proxy_list, request->home_server->proto,
+                                   packet, &proxy_listener)) {
                request->proxy_listener = proxy_listener;
                return 1;
        }
@@ -380,8 +380,8 @@ static int proxy_id_alloc(REQUEST *request, RADIUS_PACKET *packet)
                return 0;
        }
 
-       if (!fr_packet_list_id_alloc(proxy_list, packet,
-                                    &proxy_listener)) {
+       if (!fr_packet_list_id_alloc(proxy_list, request->home_server->proto,
+                                    packet, &proxy_listener)) {
                RDEBUG2("ERROR: Failed allocating Id for new socket when proxying requests.");
                return 0;
        }
@@ -525,7 +525,7 @@ static void wait_for_child_to_die(void *ctx)
                return;
        }
 
-       RDEBUG2("Child is finally responsive for request %d", request->number);
+       RDEBUG2("Child is responsive for request %d", request->number);
        remove_from_request_hash(request);
 
 #ifdef WITH_PROXY
@@ -1072,6 +1072,12 @@ static void no_response_to_proxied_request(void *ctx)
        char buffer[128];
 
        rad_assert(request->magic == REQUEST_MAGIC);
+
+       if (request->master_state == REQUEST_STOP_PROCESSING) {
+               ev_request_free(&request);
+               return;
+       }
+
        rad_assert(request->child_state == REQUEST_PROXIED);
 
        /*
@@ -1940,7 +1946,7 @@ static int proxy_request(REQUEST *request)
               inet_ntop(request->proxy->dst_ipaddr.af,
                         &request->proxy->dst_ipaddr.ipaddr,
                         buffer, sizeof(buffer)),
-              request->proxy->dst_port);
+               request->proxy->dst_port);
 
        /*
         *      Note that we set proxied BEFORE sending the packet.
@@ -3329,6 +3335,7 @@ void event_new_fd(rad_listen_t *this)
 
                        PTHREAD_MUTEX_LOCK(&proxy_mutex);
                        if (!fr_packet_list_socket_add(proxy_list, this->fd,
+                                                      sock->proto,
                                                       &sock->other_ipaddr, sock->other_port,
                                                       this)) {
                                radlog(L_ERR, "Fatal error adding socket: %s",
index 2feb8ed..4ecb5f4 100644 (file)
@@ -108,11 +108,7 @@ RADCLIENT *client_listener_find(const rad_listen_t *listener,
         */
        rad_assert(clients != NULL);
 
-       client = client_find(clients, ipaddr
-#ifdef WITH_TCP
-                            ,sock->proto
-#endif
-                            );
+       client = client_find(clients, ipaddr,sock->proto);
        if (!client) {
                char name[256], buffer[128];
                                        
@@ -191,11 +187,7 @@ RADCLIENT *client_listener_find(const rad_listen_t *listener,
                /*
                 *      Go find the enclosing network again.
                 */
-               client = client_find(clients, ipaddr
-#ifdef WITH_TCP
-                                    , sock->proto
-#endif
-                                    );
+               client = client_find(clients, ipaddr, sock->proto);
 
                /*
                 *      WTF?
@@ -844,9 +836,7 @@ static int common_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
                        return -1;
        }
 
-#ifdef WITH_TCP
        sock->proto = IPPROTO_UDP;
-#endif
 
        if (cf_pair_find(cs, "proto")) {
 #ifndef WITH_TCP
@@ -2180,9 +2170,9 @@ int proxy_new_listener(home_server *home, int src_port)
 
        sock->my_ipaddr = home->src_ipaddr;
        sock->my_port = src_port;
-       
-#ifdef WITH_TCP
        sock->proto = home->proto;
+
+#ifdef WITH_TCP
        sock->last_packet = time(NULL);
 
        if (home->proto == IPPROTO_TCP) {
index db70d8c..d868085 100644 (file)
@@ -576,8 +576,8 @@ static int home_server_add(realm_config_t *rc, CONF_SECTION *cs, int pool_type)
                }
        }
 
-#ifdef WITH_TCP
        home->proto = IPPROTO_UDP;
+#ifdef WITH_TCP
        if (hs_proto) {
                if (strcmp(hs_proto, "udp") == 0) {
                        free(hs_proto);