]> jfr.im git - solanum.git/blobdiff - ircd/s_serv.c
Resolve shfit/reduce conflict in timespec production (#54)
[solanum.git] / ircd / s_serv.c
index 316f9cfd045df95c1b80c3dac571b4154399f055..7eabf27c102de1876126bfaf827d860c82896175 100644 (file)
@@ -57,7 +57,7 @@ int MaxConnectionCount = 1;
 int MaxClientCount = 1;
 int refresh_user_links = 0;
 
-static char buf[EXT_BUFSIZE];
+static char buf[BUFSIZE];
 
 /*
  * list of recognized server capabilities.  "TS" is not on the list
@@ -103,6 +103,7 @@ unsigned int CLICAP_ECHO_MESSAGE;
 void
 init_builtin_capabs(void)
 {
+       static struct ClientCapability high_priority = {.flags = CLICAP_FLAGS_PRIORITY};
        serv_capindex = capability_index_create("server capabilities");
 
        /* These two are not set via CAPAB/GCAP keywords. */
@@ -135,13 +136,13 @@ init_builtin_capabs(void)
 
        cli_capindex = capability_index_create("client capabilities");
 
-       CLICAP_MULTI_PREFIX = capability_put(cli_capindex, "multi-prefix", NULL);
-       CLICAP_ACCOUNT_NOTIFY = capability_put(cli_capindex, "account-notify", NULL);
-       CLICAP_EXTENDED_JOIN = capability_put(cli_capindex, "extended-join", NULL);
-       CLICAP_AWAY_NOTIFY = capability_put(cli_capindex, "away-notify", NULL);
-       CLICAP_USERHOST_IN_NAMES = capability_put(cli_capindex, "userhost-in-names", NULL);
+       CLICAP_MULTI_PREFIX = capability_put(cli_capindex, "multi-prefix", &high_priority);
+       CLICAP_ACCOUNT_NOTIFY = capability_put(cli_capindex, "account-notify", &high_priority);
+       CLICAP_EXTENDED_JOIN = capability_put(cli_capindex, "extended-join", &high_priority);
+       CLICAP_AWAY_NOTIFY = capability_put(cli_capindex, "away-notify", &high_priority);
+       CLICAP_USERHOST_IN_NAMES = capability_put(cli_capindex, "userhost-in-names", &high_priority);
        CLICAP_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL);
-       CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", NULL);
+       CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", &high_priority);
        CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL);
 }
 
@@ -297,7 +298,7 @@ try_connections(void *unused)
                 */
                client_p = find_server(NULL, tmp_p->name);
 
-               if(!client_p && (CurrUsers(cltmp) < MaxUsers(cltmp)) && !connecting)
+               if(!client_p && (CurrUsers(cltmp) < MaxAutoconn(cltmp)) && !connecting)
                {
                        server_p = tmp_p;
 
@@ -372,7 +373,7 @@ check_server(const char *name, struct Client *client_p)
 
                name_matched = true;
 
-               if(rb_inet_pton_sock(client_p->sockhost, (struct sockaddr *)&client_addr) <= 0)
+               if(rb_inet_pton_sock(client_p->sockhost, &client_addr) <= 0)
                        SET_SS_FAMILY(&client_addr, AF_UNSPEC);
 
                if((tmp_p->connect_host && match(tmp_p->connect_host, client_p->host))
@@ -504,7 +505,7 @@ burst_ban(struct Client *client_p)
                         * to other servers, so rewrite to our server
                         * name.
                         */
-                       rb_strlcpy(operbuf, aconf->info.oper, sizeof buf);
+                       rb_strlcpy(operbuf, aconf->info.oper, sizeof operbuf);
                        p = strrchr(operbuf, '{');
                        if (p != NULL &&
                                        operbuf + sizeof operbuf - p > (ptrdiff_t)(melen + 2))
@@ -557,7 +558,7 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
                tlen = strlen(banptr->banstr) + (banptr->forward ? strlen(banptr->forward) + 1 : 0) + 1;
 
                /* uh oh */
-               if(cur_len + tlen > EXT_BUFSIZE - 3)
+               if(cur_len + tlen > BUFSIZE - 3)
                {
                        /* the one we're trying to send doesnt fit at all! */
                        if(cur_len == mlen)
@@ -599,7 +600,7 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr,
 static void
 burst_TS6(struct Client *client_p)
 {
-       char ubuf[EXT_BUFSIZE];
+       char ubuf[BUFSIZE];
        struct Client *target_p;
        struct Channel *chptr;
        struct membership *msptr;
@@ -669,6 +670,12 @@ burst_TS6(struct Client *client_p)
                                   use_id(target_p),
                                   target_p->user->away);
 
+               if(IsOper(target_p) && target_p->user && target_p->user->opername && target_p->user->privset)
+                       sendto_one(client_p, ":%s OPER %s %s",
+                                       use_id(target_p),
+                                       target_p->user->opername,
+                                       target_p->user->privset->name);
+
                hclientinfo.target = target_p;
                call_hook(h_burst_client, &hclientinfo);
        }
@@ -696,7 +703,7 @@ burst_TS6(struct Client *client_p)
                        if(is_voiced(msptr))
                                tlen++;
 
-                       if(cur_len + tlen >= EXT_BUFSIZE - 3)
+                       if(cur_len + tlen >= BUFSIZE - 3)
                        {
                                *(t-1) = '\0';
                                sendto_one(client_p, "%s", buf);
@@ -762,7 +769,7 @@ burst_TS6(struct Client *client_p)
 const char *
 show_capabilities(struct Client *target_p)
 {
-       static char msgbuf[EXT_BUFSIZE];
+       static char msgbuf[BUFSIZE];
 
        *msgbuf = '\0';
 
@@ -1031,8 +1038,8 @@ int
 serv_connect(struct server_conf *server_p, struct Client *by)
 {
        struct Client *client_p;
-       struct rb_sockaddr_storage sa_connect;
-       struct rb_sockaddr_storage sa_bind;
+       struct sockaddr_storage sa_connect[2];
+       struct sockaddr_storage sa_bind[ARRAY_SIZE(sa_connect)];
        char note[HOSTLEN + 10];
        rb_fde_t *F;
 
@@ -1040,8 +1047,10 @@ serv_connect(struct server_conf *server_p, struct Client *by)
        if(server_p == NULL)
                return 0;
 
-       SET_SS_FAMILY(&sa_connect, AF_UNSPEC);
-       SET_SS_FAMILY(&sa_bind, AF_UNSPEC);
+       for (int i = 0; i < ARRAY_SIZE(sa_connect); i++) {
+               SET_SS_FAMILY(&sa_connect[i], AF_UNSPEC);
+               SET_SS_FAMILY(&sa_bind[i], AF_UNSPEC);
+       }
 
        if(server_p->aftype == AF_UNSPEC
                && GET_SS_FAMILY(&server_p->connect4) == AF_INET
@@ -1049,30 +1058,48 @@ serv_connect(struct server_conf *server_p, struct Client *by)
        {
                if(rand() % 2 == 0)
                {
-                       sa_connect = server_p->connect4;
-                       sa_bind = server_p->bind4;
+                       sa_connect[0] = server_p->connect4;
+                       sa_connect[1] = server_p->connect6;
+                       sa_bind[0] = server_p->bind4;
+                       sa_bind[1] = server_p->bind6;
                }
                else
                {
-                       sa_connect = server_p->connect6;
-                       sa_bind = server_p->bind6;
+                       sa_connect[0] = server_p->connect6;
+                       sa_connect[1] = server_p->connect4;
+                       sa_bind[0] = server_p->bind6;
+                       sa_bind[1] = server_p->bind4;
                }
        }
        else if(server_p->aftype == AF_INET || GET_SS_FAMILY(&server_p->connect4) == AF_INET)
        {
-               sa_connect = server_p->connect4;
-               sa_bind = server_p->bind4;
+               sa_connect[0] = server_p->connect4;
+               sa_bind[0] = server_p->bind4;
        }
        else if(server_p->aftype == AF_INET6 || GET_SS_FAMILY(&server_p->connect6) == AF_INET6)
        {
-               sa_connect = server_p->connect6;
-               sa_bind = server_p->bind6;
+               sa_connect[0] = server_p->connect6;
+               sa_bind[0] = server_p->bind6;
        }
 
        /* log */
-       buf[0] = 0;
-       rb_inet_ntop_sock((struct sockaddr *)&sa_connect, buf, sizeof(buf));
-       ilog(L_SERVER, "Connect to *[%s] @%s", server_p->name, buf);
+#ifdef HAVE_LIBSCTP
+       if (ServerConfSCTP(server_p) && GET_SS_FAMILY(&sa_connect[1]) != AF_UNSPEC) {
+               char buf2[HOSTLEN + 1];
+
+               buf[0] = 0;
+               buf2[0] = 0;
+               rb_inet_ntop_sock((struct sockaddr *)&sa_connect[0], buf, sizeof(buf));
+               rb_inet_ntop_sock((struct sockaddr *)&sa_connect[1], buf2, sizeof(buf2));
+               ilog(L_SERVER, "Connect to *[%s] @%s&%s", server_p->name, buf, buf2);
+       } else {
+#else
+       {
+#endif
+               buf[0] = 0;
+               rb_inet_ntop_sock((struct sockaddr *)&sa_connect[0], buf, sizeof(buf));
+               ilog(L_SERVER, "Connect to *[%s] @%s", server_p->name, buf);
+       }
 
        /*
         * Make sure this server isn't already connected
@@ -1099,13 +1126,17 @@ serv_connect(struct server_conf *server_p, struct Client *by)
        }
 
        /* create a socket for the server connection */
-       if(GET_SS_FAMILY(&sa_connect) == AF_UNSPEC)
-       {
+       if(GET_SS_FAMILY(&sa_connect[0]) == AF_UNSPEC) {
                ilog_error("unspecified socket address family");
                return 0;
-       }
-       else if((F = rb_socket(GET_SS_FAMILY(&sa_connect), SOCK_STREAM, 0, NULL)) == NULL)
-       {
+#ifdef HAVE_LIBSCTP
+       } else if (ServerConfSCTP(server_p)) {
+               if ((F = rb_socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP, NULL)) == NULL) {
+                       ilog_error("opening a stream socket");
+                       return 0;
+               }
+#endif
+       } else if ((F = rb_socket(GET_SS_FAMILY(&sa_connect[0]), SOCK_STREAM, IPPROTO_TCP, NULL)) == NULL) {
                ilog_error("opening a stream socket");
                return 0;
        }
@@ -1126,7 +1157,8 @@ serv_connect(struct server_conf *server_p, struct Client *by)
        rb_strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost));
        client_p->localClient->F = F;
        /* shove the port number into the sockaddr */
-       SET_SS_PORT(&sa_connect, htons(server_p->port));
+       SET_SS_PORT(&sa_connect[0], htons(server_p->port));
+       SET_SS_PORT(&sa_connect[1], htons(server_p->port));
 
        /*
         * Set up the initial server evilness, ripped straight from
@@ -1161,19 +1193,31 @@ serv_connect(struct server_conf *server_p, struct Client *by)
        SetConnecting(client_p);
        rb_dlinkAddTail(client_p, &client_p->node, &global_client_list);
 
-       if(GET_SS_FAMILY(&sa_bind) == AF_UNSPEC)
-       {
-               if(GET_SS_FAMILY(&sa_connect) == GET_SS_FAMILY(&ServerInfo.bind4))
-                       sa_bind = ServerInfo.bind4;
-               if(GET_SS_FAMILY(&sa_connect) == GET_SS_FAMILY(&ServerInfo.bind6))
-                       sa_bind = ServerInfo.bind6;
+       for (int i = 0; i < ARRAY_SIZE(sa_connect); i++) {
+               if (GET_SS_FAMILY(&sa_bind[i]) == AF_UNSPEC) {
+                       if (GET_SS_FAMILY(&sa_connect[i]) == GET_SS_FAMILY(&ServerInfo.bind4))
+                               sa_bind[i] = ServerInfo.bind4;
+                       if (GET_SS_FAMILY(&sa_connect[i]) == GET_SS_FAMILY(&ServerInfo.bind6))
+                               sa_bind[i] = ServerInfo.bind6;
+               }
        }
 
-       rb_connect_tcp(client_p->localClient->F,
-               (struct sockaddr *)&sa_connect,
-               GET_SS_FAMILY(&sa_bind) == AF_UNSPEC ? NULL : (struct sockaddr *)&sa_bind,
-               ServerConfSSL(server_p) ? serv_connect_ssl_callback : serv_connect_callback,
-               client_p, ConfigFileEntry.connect_timeout);
+#ifdef HAVE_LIBSCTP
+       if (ServerConfSCTP(server_p)) {
+               rb_connect_sctp(client_p->localClient->F,
+                       sa_connect, ARRAY_SIZE(sa_connect), sa_bind, ARRAY_SIZE(sa_bind),
+                       ServerConfSSL(server_p) ? serv_connect_ssl_callback : serv_connect_callback,
+                       client_p, ConfigFileEntry.connect_timeout);
+       } else {
+#else
+       {
+#endif
+               rb_connect_tcp(client_p->localClient->F,
+                       (struct sockaddr *)&sa_connect[0],
+                       GET_SS_FAMILY(&sa_bind[0]) == AF_UNSPEC ? NULL : (struct sockaddr *)&sa_bind[0],
+                       ServerConfSSL(server_p) ? serv_connect_ssl_callback : serv_connect_callback,
+                       client_p, ConfigFileEntry.connect_timeout);
+       }
        return 1;
 }