]> jfr.im git - solanum.git/commitdiff
listener: use exit_client instead of free_client
authorSimon Arlott <sa.me.uk>
Sun, 20 Nov 2016 20:43:53 +0000 (20:43 +0000)
committerSimon Arlott <sa.me.uk>
Sun, 20 Nov 2016 21:09:07 +0000 (21:09 +0000)
As well as leaking a connid and leaving the connection open,
these calls to free_client() leave the client in the unknown_list
causing check_unknowns_list() to crash when either ptr->data
(ptr being the freed client_p->localClient->tnode) is NULL or
when client_p->localClient is NULL.

Flag the client as an IO error so that we don't try to send it
any data (as this is not a normal plaintext connection).

include/client.h
ircd/client.c
ircd/listener.c

index 708bf69dc5d3923c71f777b025124ef7fa4da9a0..39f31e776e50e4719a219faa6e125d09f879f58a 100644 (file)
@@ -585,7 +585,6 @@ extern int is_remote_connect(struct Client *);
 extern void init_client(void);
 extern struct Client *make_client(struct Client *from);
 extern void free_pre_client(struct Client *client);
-extern void free_client(struct Client *client);
 
 extern int exit_client(struct Client *, struct Client *, struct Client *, const char *);
 
index 87f0b3b8b338b00afca289ae3445c5569b6222c3..56872517c3524ef3395c22b7ea8954b916fe008f 100644 (file)
@@ -328,7 +328,7 @@ free_local_client(struct Client *client_p)
        client_p->localClient = NULL;
 }
 
-void
+static void
 free_client(struct Client *client_p)
 {
        s_assert(NULL != client_p);
index ba4a11505b0713177915d7bbfd78ccc7393f8d47..2e76c133f5a1d277f42853337564312cbdb736df 100644 (file)
@@ -457,13 +457,27 @@ add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, str
         * the client has already been checked out in accept_connection
         */
        new_client = make_client(NULL);
+       new_client->localClient->F = F;
+
+       memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage));
+       memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage));
+
+       /*
+        * copy address to 'sockhost' as a string, copy it to host too
+        * so we have something valid to put into error messages...
+        */
+       rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost,
+               sizeof(new_client->sockhost));
+
+       rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));
 
        if (listener->ssl)
        {
                rb_fde_t *xF[2];
                if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1)
                {
-                       free_client(new_client);
+                       SetIOError(new_client);
+                       exit_client(new_client, new_client, new_client, "Fatal Error");
                        return;
                }
                new_client->localClient->ssl_callback = accept_sslcallback;
@@ -471,10 +485,12 @@ add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, str
                new_client->localClient->ssl_ctl = start_ssld_accept(F, xF[1], connid_get(new_client));        /* this will close F for us */
                if(new_client->localClient->ssl_ctl == NULL)
                {
-                       free_client(new_client);
+                       SetIOError(new_client);
+                       exit_client(new_client, new_client, new_client, "Service Unavailable");
                        return;
                }
                F = xF[0];
+               new_client->localClient->F = F;
                SetSSL(new_client);
        }
 
@@ -483,32 +499,21 @@ add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, str
                rb_fde_t *xF[2];
                if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming wsockd Connection") == -1)
                {
-                       free_client(new_client);
+                       SetIOError(new_client);
+                       exit_client(new_client, new_client, new_client, "Fatal Error");
                        return;
                }
                new_client->localClient->ws_ctl = start_wsockd_accept(F, xF[1], connid_get(new_client));        /* this will close F for us */
                if(new_client->localClient->ws_ctl == NULL)
                {
-                       free_client(new_client);
+                       SetIOError(new_client);
+                       exit_client(new_client, new_client, new_client, "Service Unavailable");
                        return;
                }
                F = xF[0];
+               new_client->localClient->F = F;
        }
 
-       memcpy(&new_client->localClient->ip, sai, sizeof(struct rb_sockaddr_storage));
-       memcpy(&new_client->preClient->lip, lai, sizeof(struct rb_sockaddr_storage));
-
-       /*
-        * copy address to 'sockhost' as a string, copy it to host too
-        * so we have something valid to put into error messages...
-        */
-       rb_inet_ntop_sock((struct sockaddr *)&new_client->localClient->ip, new_client->sockhost,
-               sizeof(new_client->sockhost));
-
-
-       rb_strlcpy(new_client->host, new_client->sockhost, sizeof(new_client->host));
-
-       new_client->localClient->F = F;
        new_client->localClient->listener = listener;
 
        ++listener->ref_count;