]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - src/listener.c
Added m_cycle and added it to all the appropriate locations.
[irc/rqf/shadowircd.git] / src / listener.c
index 0ab90c2bcbbced248a87973f3c682f3682eec590..489aee7ec648b452ec8a2f8c25325f26cfe9e011 100644 (file)
@@ -28,8 +28,7 @@
 #include "setup.h"
 #include "listener.h"
 #include "client.h"
-#include "irc_string.h"
-#include "sprintf_irc.h"
+#include "match.h"
 #include "ircd.h"
 #include "ircd_defs.h"
 #include "numeric.h"
@@ -53,14 +52,14 @@ static const struct in6_addr in6addr_any =
 { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } };
 #endif 
 
-static listener_t *ListenerPollList = NULL;
+static struct Listener *ListenerPollList = NULL;
 static int accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data);
 static void accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t addrlen, void *data);
 
-static listener_t *
+static struct Listener *
 make_listener(struct rb_sockaddr_storage *addr)
 {
-       listener_t *listener = (listener_t *) rb_malloc(sizeof(listener_t));
+       struct Listener *listener = (struct Listener *) rb_malloc(sizeof(struct Listener));
        s_assert(0 != listener);
        listener->name = me.name;
        listener->F = NULL;
@@ -71,7 +70,7 @@ make_listener(struct rb_sockaddr_storage *addr)
 }
 
 void
-free_listener(listener_t *listener)
+free_listener(struct Listener *listener)
 {
        s_assert(NULL != listener);
        if(listener == NULL)
@@ -83,7 +82,7 @@ free_listener(listener_t *listener)
                ListenerPollList = listener->next;
        else
        {
-               listener_t *prev = ListenerPollList;
+               struct Listener *prev = ListenerPollList;
                for (; prev; prev = prev->next)
                {
                        if(listener == prev->next)
@@ -105,7 +104,7 @@ free_listener(listener_t *listener)
  * returns "host.foo.org:6667" for a given listener
  */
 const char *
-get_listener_name(const listener_t *listener)
+get_listener_name(const struct Listener *listener)
 {
        static char buf[HOSTLEN + HOSTLEN + PORTNAMELEN + 4];
        int port = 0;
@@ -134,7 +133,7 @@ get_listener_name(const listener_t *listener)
 void
 show_ports(struct Client *source_p)
 {
-       listener_t *listener = 0;
+       struct Listener *listener = 0;
 
        for (listener = ListenerPollList; listener; listener = listener->next)
        {
@@ -166,7 +165,7 @@ show_ports(struct Client *source_p)
 #endif
 
 static int
-inetport(listener_t *listener)
+inetport(struct Listener *listener)
 {
        rb_fde_t *F;
        int ret;
@@ -246,11 +245,11 @@ inetport(listener_t *listener)
        return 1;
 }
 
-static listener_t *
+static struct Listener *
 find_listener(struct rb_sockaddr_storage *addr)
 {
-       listener_t *listener = NULL;
-       listener_t *last_closed = NULL;
+       struct Listener *listener = NULL;
+       struct Listener *last_closed = NULL;
 
        for (listener = ListenerPollList; listener; listener = listener->next)
        {
@@ -308,7 +307,7 @@ find_listener(struct rb_sockaddr_storage *addr)
 void
 add_listener(int port, const char *vhost_ip, int family, int ssl)
 {
-       listener_t *listener;
+       struct Listener *listener;
        struct rb_sockaddr_storage vaddr;
 
        /*
@@ -390,7 +389,7 @@ add_listener(int port, const char *vhost_ip, int family, int ssl)
  * close_listener - close a single listener
  */
 void
-close_listener(listener_t *listener)
+close_listener(struct Listener *listener)
 {
        s_assert(listener != NULL);
        if(listener == NULL)
@@ -415,8 +414,8 @@ close_listener(listener_t *listener)
 void
 close_listeners()
 {
-       listener_t *listener;
-       listener_t *listener_next = 0;
+       struct Listener *listener;
+       struct Listener *listener_next = 0;
        /*
         * close all 'extra' listening ports we have
         */
@@ -436,7 +435,7 @@ close_listeners()
  * any client list yet.
  */
 static void
-add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, void *ssl_ctl, int exempt)
+add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, struct sockaddr *lai, void *ssl_ctl)
 {
        struct Client *new_client;
        s_assert(NULL != listener);
@@ -448,6 +447,7 @@ add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, voi
        new_client = make_client(NULL);
 
        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
@@ -468,17 +468,11 @@ add_connection(struct Listener *listener, rb_fde_t *F, struct sockaddr *sai, voi
 
        ++listener->ref_count;
 
-       if(!exempt)
-       {
-               if(check_reject(new_client))
-                       return; 
-               if(add_unknown_ip(new_client))
-                       return;
-       }
-
        start_auth(new_client);
 }
 
+static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
+
 static int
 accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
 {
@@ -513,7 +507,7 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
                return 0;
        }
 
-       aconf = find_dline(addr, AF_INET);
+       aconf = find_dline(addr, addr->sa_family);
        if(aconf != NULL && (aconf->status & CONF_EXEMPTDLINE))
                return 1;
        
@@ -540,6 +534,16 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
                return 0;
        }
 
+       if(check_reject(F, addr))
+               return 0;
+               
+       if(throttle_add(addr))
+       {
+               rb_write(F, toofast, strlen(toofast));
+               rb_close(F);
+               return 0;
+       }
+
        return 1;
 }
 
@@ -548,9 +552,14 @@ accept_ssld(rb_fde_t *F, struct sockaddr *addr, struct sockaddr *laddr, struct L
 {
        ssl_ctl_t *ctl;
        rb_fde_t *xF[2];
-       rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection");
+       if(rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF[0], &xF[1], "Incoming ssld Connection") == -1)
+       {
+               ilog_error("creating SSL/TLS socket pairs");
+               rb_close(F);
+               return;
+       }
        ctl = start_ssld_accept(F, xF[1], rb_get_fd(xF[0])); /* this will close F for us */
-       add_connection(listener, xF[0], addr, ctl, 1);
+       add_connection(listener, xF[0], addr, laddr, ctl);
 }
 
 static void
@@ -564,13 +573,13 @@ accept_callback(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t add
 
        if(getsockname(rb_get_fd(F), (struct sockaddr *) &lip, &locallen) < 0)
        {
-               /* this shouldn't fail so... */
-               /* XXX add logging of this */
+               /* this can fail if the connection disappeared in the meantime */
                rb_close(F);
+               return;
        }
        
        if(listener->ssl)
                accept_ssld(F, addr, (struct sockaddr *)&lip, listener);
        else
-               add_connection(listener, F, addr, NULL, 1);
+               add_connection(listener, F, addr, (struct sockaddr *)&lip, NULL);
 }