X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/ff12cc94790de2e87e78ee7aa378f21fa415d73c..bfc44622c8d3c9b94e89ee169e0e04d61adcc098:/ircd/s_serv.c diff --git a/ircd/s_serv.c b/ircd/s_serv.c index cf1a2b66..208a6fe1 100644 --- a/ircd/s_serv.c +++ b/ircd/s_serv.c @@ -20,8 +20,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA - * - * $Id: s_serv.c 3550 2007-08-09 06:47:26Z nenolod $ */ #include "stdinc.h" @@ -40,7 +38,6 @@ #include "ircd_defs.h" #include "numeric.h" #include "packet.h" -#include "res.h" #include "s_conf.h" #include "s_newconf.h" #include "logger.h" @@ -73,6 +70,7 @@ static char buf[BUFSIZE]; * extra argument to "PASS" takes care of checking that. -orabidoo */ struct CapabilityIndex *serv_capindex = NULL; +struct CapabilityIndex *cli_capindex = NULL; unsigned int CAP_CAP; unsigned int CAP_QS; @@ -95,6 +93,15 @@ unsigned int CAP_EOPMOD; unsigned int CAP_BAN; unsigned int CAP_MLOCK; +unsigned int CLICAP_MULTI_PREFIX; +unsigned int CLICAP_ACCOUNT_NOTIFY; +unsigned int CLICAP_EXTENDED_JOIN; +unsigned int CLICAP_AWAY_NOTIFY; +unsigned int CLICAP_USERHOST_IN_NAMES; +unsigned int CLICAP_CAP_NOTIFY; +unsigned int CLICAP_CHGHOST; +unsigned int CLICAP_ECHO_MESSAGE; + /* * initialize our builtin capability table. --nenolod */ @@ -107,29 +114,40 @@ init_builtin_capabs(void) CAP_CAP = capability_put_anonymous(serv_capindex); CAP_TS6 = capability_put_anonymous(serv_capindex); - CAP_QS = capability_put(serv_capindex, "QS"); - CAP_EX = capability_put(serv_capindex, "EX"); - CAP_CHW = capability_put(serv_capindex, "CHW"); - CAP_IE = capability_put(serv_capindex, "IE"); - CAP_KLN = capability_put(serv_capindex, "KLN"); - CAP_KNOCK = capability_put(serv_capindex, "KNOCK"); - CAP_ZIP = capability_put(serv_capindex, "ZIP"); - CAP_TB = capability_put(serv_capindex, "TB"); - CAP_UNKLN = capability_put(serv_capindex, "UNKLN"); - CAP_CLUSTER = capability_put(serv_capindex, "CLUSTER"); - CAP_ENCAP = capability_put(serv_capindex, "ENCAP"); - CAP_SERVICE = capability_put(serv_capindex, "SERVICES"); - CAP_RSFNC = capability_put(serv_capindex, "RSFNC"); - CAP_SAVE = capability_put(serv_capindex, "SAVE"); - CAP_EUID = capability_put(serv_capindex, "EUID"); - CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD"); - CAP_BAN = capability_put(serv_capindex, "BAN"); - CAP_MLOCK = capability_put(serv_capindex, "MLOCK"); + CAP_QS = capability_put(serv_capindex, "QS", NULL); + CAP_EX = capability_put(serv_capindex, "EX", NULL); + CAP_CHW = capability_put(serv_capindex, "CHW", NULL); + CAP_IE = capability_put(serv_capindex, "IE", NULL); + CAP_KLN = capability_put(serv_capindex, "KLN", NULL); + CAP_KNOCK = capability_put(serv_capindex, "KNOCK", NULL); + CAP_ZIP = capability_put(serv_capindex, "ZIP", NULL); + CAP_TB = capability_put(serv_capindex, "TB", NULL); + CAP_UNKLN = capability_put(serv_capindex, "UNKLN", NULL); + CAP_CLUSTER = capability_put(serv_capindex, "CLUSTER", NULL); + CAP_ENCAP = capability_put(serv_capindex, "ENCAP", NULL); + CAP_SERVICE = capability_put(serv_capindex, "SERVICES", NULL); + CAP_RSFNC = capability_put(serv_capindex, "RSFNC", NULL); + CAP_SAVE = capability_put(serv_capindex, "SAVE", NULL); + CAP_EUID = capability_put(serv_capindex, "EUID", NULL); + CAP_EOPMOD = capability_put(serv_capindex, "EOPMOD", NULL); + CAP_BAN = capability_put(serv_capindex, "BAN", NULL); + CAP_MLOCK = capability_put(serv_capindex, "MLOCK", NULL); capability_require(serv_capindex, "QS"); capability_require(serv_capindex, "EX"); capability_require(serv_capindex, "IE"); capability_require(serv_capindex, "ENCAP"); + + 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_CAP_NOTIFY = capability_put(cli_capindex, "cap-notify", NULL); + CLICAP_CHGHOST = capability_put(cli_capindex, "chghost", NULL); + CLICAP_ECHO_MESSAGE = capability_put(cli_capindex, "echo-message", NULL); } static CNCB serv_connect_callback; @@ -243,7 +261,7 @@ try_connections(void *unused) struct server_conf *tmp_p; struct Class *cltmp; rb_dlink_node *ptr; - int connecting = FALSE; + bool connecting = false; int confrq = 0; time_t next = 0; @@ -255,7 +273,7 @@ try_connections(void *unused) continue; /* don't allow ssl connections if ssl isn't setup */ - if(ServerConfSSL(tmp_p) && (!ssl_ok || !get_ssld_count())) + if(ServerConfSSL(tmp_p) && (!ircd_ssl_ok || !get_ssld_count())) continue; cltmp = tmp_p->class; @@ -288,7 +306,7 @@ try_connections(void *unused) server_p = tmp_p; /* We connect only one at time... */ - connecting = TRUE; + connecting = true; } if((next > tmp_p->hold) || (next == 0)) @@ -418,7 +436,6 @@ check_server(const char *name, struct Client *client_p) * - int flag of capabilities that this server has * output - NONE * side effects - send the CAPAB line to a server -orabidoo - * */ void send_capabilities(struct Client *client_p, unsigned int cap_can_send) @@ -504,7 +521,7 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr, int mlen; int cur_len; - cur_len = mlen = rb_sprintf(buf, ":%s BMASK %ld %s %c :", + cur_len = mlen = sprintf(buf, ":%s BMASK %ld %s %c :", me.id, (long) chptr->channelts, chptr->chname, flag); t = buf + mlen; @@ -532,9 +549,9 @@ burst_modes_TS6(struct Client *client_p, struct Channel *chptr, } if (banptr->forward) - rb_sprintf(t, "%s$%s ", banptr->banstr, banptr->forward); + sprintf(t, "%s$%s ", banptr->banstr, banptr->forward); else - rb_sprintf(t, "%s ", banptr->banstr); + sprintf(t, "%s ", banptr->banstr); t += tlen; cur_len += tlen; } @@ -635,7 +652,7 @@ burst_TS6(struct Client *client_p) if(*chptr->chname != '#') continue; - cur_len = mlen = rb_sprintf(buf, ":%s SJOIN %ld %s %s :", me.id, + cur_len = mlen = sprintf(buf, ":%s SJOIN %ld %s %s :", me.id, (long) chptr->channelts, chptr->chname, channel_modes(chptr, client_p)); @@ -659,7 +676,7 @@ burst_TS6(struct Client *client_p) t = buf + mlen; } - rb_sprintf(t, "%s%s ", find_channel_status(msptr, 1), + sprintf(t, "%s%s ", find_channel_status(msptr, 1), use_id(msptr->client_p)); cur_len += tlen; @@ -869,7 +886,7 @@ server_estab(struct Client *client_p) hdata.target = client_p; call_hook(h_server_introduced, &hdata); - rb_snprintf(note, sizeof(note), "Server: %s", client_p->name); + snprintf(note, sizeof(note), "Server: %s", client_p->name); rb_note(client_p->localClient->F, note); /* @@ -971,135 +988,6 @@ server_estab(struct Client *client_p) * -- adrian */ -static int -serv_connect_resolved(struct Client *client_p) -{ - struct rb_sockaddr_storage myipnum; - char vhoststr[HOSTIPLEN]; - struct server_conf *server_p; - uint16_t port; - - if((server_p = client_p->localClient->att_sconf) == NULL) - { - sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Lost connect{} block for %s", - client_p->name); - exit_client(client_p, client_p, &me, "Lost connect{} block"); - return 0; - } - -#ifdef RB_IPV6 - if(client_p->localClient->ip.ss_family == AF_INET6) - port = ntohs(((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port); - else -#endif - port = ntohs(((struct sockaddr_in *)&client_p->localClient->ip)->sin_port); - - if(ServerConfVhosted(server_p)) - { - memcpy(&myipnum, &server_p->my_ipnum, sizeof(server_p->my_ipnum)); - ((struct sockaddr_in *)&myipnum)->sin_port = 0; - myipnum.ss_family = server_p->aftype; - - } - else if(server_p->aftype == AF_INET && ServerInfo.specific_ipv4_vhost) - { - memcpy(&myipnum, &ServerInfo.ip, sizeof(ServerInfo.ip)); - ((struct sockaddr_in *)&myipnum)->sin_port = 0; - myipnum.ss_family = AF_INET; - SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in)); - } - -#ifdef RB_IPV6 - else if((server_p->aftype == AF_INET6) && ServerInfo.specific_ipv6_vhost) - { - memcpy(&myipnum, &ServerInfo.ip6, sizeof(ServerInfo.ip6)); - ((struct sockaddr_in6 *)&myipnum)->sin6_port = 0; - myipnum.ss_family = AF_INET6; - SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6)); - } -#endif - else - { - /* log */ - ilog(L_SERVER, "Connecting to %s[%s] port %d (%s)", client_p->name, client_p->sockhost, port, -#ifdef RB_IPV6 - server_p->aftype == AF_INET6 ? "IPv6" : -#endif - (server_p->aftype == AF_INET ? "IPv4" : "?")); - - if(ServerConfSSL(server_p)) - { - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - NULL, 0, serv_connect_ssl_callback, - client_p, ConfigFileEntry.connect_timeout); - } - else - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - NULL, 0, serv_connect_callback, - client_p, ConfigFileEntry.connect_timeout); - return 1; - } - - /* log */ - rb_inet_ntop_sock((struct sockaddr *)&myipnum, vhoststr, sizeof vhoststr); - ilog(L_SERVER, "Connecting to %s[%s] port %d (%s) (vhost %s)", client_p->name, client_p->sockhost, port, -#ifdef RB_IPV6 - server_p->aftype == AF_INET6 ? "IPv6" : -#endif - (server_p->aftype == AF_INET ? "IPv4" : "?"), vhoststr); - - - if(ServerConfSSL(server_p)) - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - (struct sockaddr *) &myipnum, - GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p, - ConfigFileEntry.connect_timeout); - else - rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&client_p->localClient->ip, - (struct sockaddr *) &myipnum, - GET_SS_LEN(&myipnum), serv_connect_callback, client_p, - ConfigFileEntry.connect_timeout); - - return 1; -} - -static void -serv_connect_dns_callback(void *vptr, struct DNSReply *reply) -{ - struct Client *client_p = vptr; - uint16_t port; - - rb_free(client_p->localClient->dnsquery); - client_p->localClient->dnsquery = NULL; - - if (reply == NULL) - { - sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL, "Cannot resolve hostname for %s", - client_p->name); - ilog(L_SERVER, "Cannot resolve hostname for %s", - log_client_name(client_p, HIDE_IP)); - exit_client(client_p, client_p, &me, "Cannot resolve hostname"); - return; - } -#ifdef RB_IPV6 - if(reply->addr.ss_family == AF_INET6) - port = ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port; - else -#endif - port = ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port; - memcpy(&client_p->localClient->ip, &reply->addr, sizeof(client_p->localClient->ip)); -#ifdef RB_IPV6 - if(reply->addr.ss_family == AF_INET6) - ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = port; - else -#endif - ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = port; - /* Set sockhost properly now -- jilles */ - rb_inet_ntop_sock((struct sockaddr *)&client_p->localClient->ip, - client_p->sockhost, sizeof client_p->sockhost); - serv_connect_resolved(client_p); -} - /* * serv_connect() - initiate a server connection * @@ -1121,14 +1009,18 @@ int serv_connect(struct server_conf *server_p, struct Client *by) { struct Client *client_p; - struct rb_sockaddr_storage theiripnum; - rb_fde_t *F; + struct rb_sockaddr_storage myipnum; char note[HOSTLEN + 10]; + rb_fde_t *F; s_assert(server_p != NULL); if(server_p == NULL) return 0; + /* log */ + rb_inet_ntop_sock((struct sockaddr *)&server_p->my_ipnum, buf, sizeof(buf)); + ilog(L_SERVER, "Connect to *[%s] @%s", server_p->name, buf); + /* * Make sure this server isn't already connected */ @@ -1144,27 +1036,31 @@ serv_connect(struct server_conf *server_p, struct Client *by) } /* create a socket for the server connection */ - if((F = rb_socket(server_p->aftype, SOCK_STREAM, 0, NULL)) == NULL) + if((F = rb_socket(GET_SS_FAMILY(&server_p->my_ipnum), SOCK_STREAM, 0, NULL)) == NULL) { ilog_error("opening a stream socket"); return 0; } - rb_snprintf(note, sizeof note, "Server: %s", server_p->name); + /* servernames are always guaranteed under HOSTLEN chars */ + snprintf(note, sizeof(note), "Server: %s", server_p->name); rb_note(F, note); /* Create a local client */ client_p = make_client(NULL); - /* Copy in the server, hostname, fd - * The sockhost may be a hostname, this will be corrected later - * -- jilles - */ + /* Copy in the server, hostname, fd */ rb_strlcpy(client_p->name, server_p->name, sizeof(client_p->name)); rb_strlcpy(client_p->host, server_p->host, sizeof(client_p->host)); - rb_strlcpy(client_p->sockhost, server_p->host, sizeof(client_p->sockhost)); + rb_strlcpy(client_p->sockhost, buf, sizeof(client_p->sockhost)); client_p->localClient->F = F; - add_to_cli_connid_hash(client_p); + /* shove the port number into the sockaddr */ +#ifdef RB_IPV6 + if(GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET6) + ((struct sockaddr_in6 *)&server_p->my_ipnum)->sin6_port = htons(server_p->port); + else +#endif + ((struct sockaddr_in *)&server_p->my_ipnum)->sin_port = htons(server_p->port); /* * Set up the initial server evilness, ripped straight from @@ -1191,57 +1087,67 @@ serv_connect(struct server_conf *server_p, struct Client *by) * The socket has been connected or connect is in progress. */ make_server(client_p); - if(by && IsPerson(by)) - { - rb_strlcpy(client_p->serv->by, by->name, - sizeof client_p->serv->by); - if(client_p->serv->user) - free_user(client_p->serv->user, NULL); - client_p->serv->user = by->user; - by->user->refcnt++; - } + if(by && IsClient(by)) + strcpy(client_p->serv->by, by->name); else - { - rb_strlcpy(client_p->serv->by, "AutoConn.", - sizeof client_p->serv->by); - if(client_p->serv->user) - free_user(client_p->serv->user, NULL); - client_p->serv->user = NULL; - } + strcpy(client_p->serv->by, "AutoConn."); + SetConnecting(client_p); rb_dlinkAddTail(client_p, &client_p->node, &global_client_list); - if (rb_inet_pton_sock(server_p->host, (struct sockaddr *)&theiripnum) > 0) + if(ServerConfVhosted(server_p)) { - memcpy(&client_p->localClient->ip, &theiripnum, sizeof(client_p->localClient->ip)); -#ifdef RB_IPV6 - if(theiripnum.ss_family == AF_INET6) - ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port); - else -#endif - ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port); + memcpy(&myipnum, &server_p->my_ipnum, sizeof(myipnum)); + ((struct sockaddr_in *)&myipnum)->sin_port = 0; + SET_SS_FAMILY(&myipnum, GET_SS_FAMILY(&server_p->my_ipnum)); - return serv_connect_resolved(client_p); } - else + else if(GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET && ServerInfo.specific_ipv4_vhost) { -#ifdef RB_IPV6 - if(theiripnum.ss_family == AF_INET6) - ((struct sockaddr_in6 *)&client_p->localClient->ip)->sin6_port = htons(server_p->port); - else -#endif - ((struct sockaddr_in *)&client_p->localClient->ip)->sin_port = htons(server_p->port); + memcpy(&myipnum, &ServerInfo.ip, sizeof(myipnum)); + ((struct sockaddr_in *)&myipnum)->sin_port = 0; + SET_SS_FAMILY(&myipnum, AF_INET); + SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in)); + } - client_p->localClient->dnsquery = rb_malloc(sizeof(struct DNSQuery)); - client_p->localClient->dnsquery->ptr = client_p; - client_p->localClient->dnsquery->callback = serv_connect_dns_callback; - gethost_byname_type(server_p->host, client_p->localClient->dnsquery, #ifdef RB_IPV6 - server_p->aftype == AF_INET6 ? T_AAAA : + else if((GET_SS_FAMILY(&server_p->my_ipnum) == AF_INET6) && ServerInfo.specific_ipv6_vhost) + { + memcpy(&myipnum, &ServerInfo.ip6, sizeof(myipnum)); + ((struct sockaddr_in6 *)&myipnum)->sin6_port = 0; + SET_SS_FAMILY(&myipnum, AF_INET6); + SET_SS_LEN(&myipnum, sizeof(struct sockaddr_in6)); + } #endif - T_A); + else + { + if(ServerConfSSL(server_p)) + { + rb_connect_tcp(client_p->localClient->F, + (struct sockaddr *)&server_p->my_ipnum, NULL, 0, + serv_connect_ssl_callback, client_p, + ConfigFileEntry.connect_timeout); + } + else + rb_connect_tcp(client_p->localClient->F, + (struct sockaddr *)&server_p->my_ipnum, NULL, 0, + serv_connect_callback, client_p, + ConfigFileEntry.connect_timeout); + return 1; } + if(ServerConfSSL(server_p)) + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&server_p->my_ipnum, + (struct sockaddr *)&myipnum, + GET_SS_LEN(&myipnum), serv_connect_ssl_callback, client_p, + ConfigFileEntry.connect_timeout); + else + rb_connect_tcp(client_p->localClient->F, (struct sockaddr *)&server_p->my_ipnum, + (struct sockaddr *)&myipnum, + GET_SS_LEN(&myipnum), serv_connect_callback, client_p, + ConfigFileEntry.connect_timeout); + + return 1; } static void @@ -1263,11 +1169,14 @@ serv_connect_ssl_callback(rb_fde_t *F, int status, void *data) return; } - del_from_cli_connid_hash(client_p); client_p->localClient->F = xF[0]; - add_to_cli_connid_hash(client_p); client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], rb_get_fd(xF[0])); + if(!client_p->localClient->ssl_ctl) + { + serv_connect_callback(client_p->localClient->F, RB_ERROR, data); + return; + } SetSSL(client_p); serv_connect_callback(client_p->localClient->F, RB_OK, client_p); }