diff --git a/include/dns.h b/include/dns.h index ba501e0a..23a88f51 100644 --- a/include/dns.h +++ b/include/dns.h @@ -30,9 +30,9 @@ typedef void DNSCB(const char *res, int status, int aftype, void *data); void init_resolver(void); void restart_resolver(void); void rehash_resolver(void); -uint16_t __rb_must_check lookup_hostname(const char *hostname, int aftype, DNSCB * callback, void *data); -uint16_t __rb_must_check lookup_ip(const char *hostname, int aftype, DNSCB * callback, void *data); -void cancel_lookup(uint16_t xid); +uint32_t __rb_must_check lookup_hostname(const char *hostname, int aftype, DNSCB * callback, void *data); +uint32_t __rb_must_check lookup_ip(const char *hostname, int aftype, DNSCB * callback, void *data); +void cancel_lookup(uint32_t xid); void report_dns_servers(struct Client *); void rehash_dns_vhost(void); diff --git a/include/s_newconf.h b/include/s_newconf.h index 9e24d931..590e68e4 100644 --- a/include/s_newconf.h +++ b/include/s_newconf.h @@ -200,7 +200,7 @@ struct server_conf int flags; int servers; - uint16_t dns_query; + uint32_t dns_query; }; #define SERVER_ILLEGAL 0x0001 diff --git a/include/stdinc.h b/include/stdinc.h index 5d410122..6bf8f132 100644 --- a/include/stdinc.h +++ b/include/stdinc.h @@ -164,40 +164,37 @@ extern int errno; #endif - -#ifdef strdupa -#define LOCAL_COPY(s) strdupa(s) -#else -#if defined(__INTEL_COMPILER) || defined(__GNUC__) -# define LOCAL_COPY(s) __extension__({ char *_s = alloca(strlen(s) + 1); strcpy(_s, s); _s; }) +/* unconditionally use our own strdupa/strndupa. + * if you use a compiler other than these, fix it yourself + * these macros were lifted from glibc + */ +#if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__clang__) +#define LOCAL_COPY(s) \ + (__extension__ \ + ({ \ + const char *__old = (s); \ + size_t __len = strlen (__old) + 1; \ + char *__new = (char *) __builtin_alloca (__len); \ + (char *) memcpy (__new, __old, __len); \ + })) #else -# define LOCAL_COPY(s) strcpy(alloca(strlen(s) + 1), s) /* XXX Is that allowed? */ -#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */ -#endif /* strdupa */ +#error "does your compiler support strdup/alloca?" +#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__clang__) */ /* LOCAL_COPY_N copies n part of string and adds one to terminate the string */ -#ifdef strndupa -#define LOCAL_COPY_N(s, n) strndupa(s, n) -#else -#if defined(__INTEL_COMPILER) || defined(__GNUC__) -#define LOCAL_COPY_N(s, n) __extension__({ size_t _l = strlen(s); _l = n > _l ? _l : n; char *_s = alloca(_l+1); memcpy(_s, s, _l); _s[_l] = '\0' ; _s; }) +#if defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__clang__) +# define LOCAL_COPY_N(s, n) \ + (__extension__ \ + ({ \ + const char *__old = (s); \ + size_t __len = strnlen (__old, (n)); \ + char *__new = (char *) __builtin_alloca (__len + 1); \ + __new[__len] = '\0'; \ + (char *) memcpy (__new, __old, __len); \ + })) #else -#define LOCAL_COPY_N(s, n) xc_strlcpy(alloca(strlen(s)+1), s, n) -INLINE_FUNC size_t -xc_strlcpy(char *dest, const char *src, size_t size) -{ - size_t ret = strlen(src); - - if(size) - { - size_t len = (ret >= size) ? size - 1 : ret; - memcpy(dest, src, len); - dest[len] = '\0'; - } - return dest; -} -#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */ -#endif /* strndupa */ +#error "does your compiler support strndup/alloca?" +#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) || defined(__clang__) */ #ifndef INADDR_NONE # define INADDR_NONE ((in_addr_t) 0xffffffff) diff --git a/libratbox/include/rb_commio.h b/libratbox/include/rb_commio.h index 870c6bc2..79f60f47 100644 --- a/libratbox/include/rb_commio.h +++ b/libratbox/include/rb_commio.h @@ -68,6 +68,7 @@ typedef enum _rb_tls_ver RB_TLS_VER_TLS1, RB_TLS_VER_TLS1_1, RB_TLS_VER_TLS1_2, + RB_TLS_VER_TLS1_3, RB_TLS_VER_LAST, } rb_tls_ver_t; diff --git a/libratbox/include/rb_rawbuf.h b/libratbox/include/rb_rawbuf.h index 2586cc18..6b03a0a7 100644 --- a/libratbox/include/rb_rawbuf.h +++ b/libratbox/include/rb_rawbuf.h @@ -36,7 +36,9 @@ typedef struct _rb_rawbuf_head rb_rawbuf_head_t; void rb_init_rawbuffers(void); void rb_free_rawbuffer(rb_rawbuf_head_t *); rb_rawbuf_head_t *rb_new_rawbuffer(void); +#if 0 size_t rb_rawbuf_get(rb_rawbuf_head_t *, void *data, size_t len); +#endif void rb_rawbuf_append(rb_rawbuf_head_t *, void *data, size_t len); ssize_t rb_rawbuf_flush(rb_rawbuf_head_t *, rb_fde_t *F); size_t rb_rawbuf_length(rb_rawbuf_head_t * rb); diff --git a/libratbox/src/export-syms.txt b/libratbox/src/export-syms.txt index d669f2cb..6f4cdd42 100644 --- a/libratbox/src/export-syms.txt +++ b/libratbox/src/export-syms.txt @@ -104,7 +104,6 @@ rb_patricia_search_exact rb_pipe rb_rawbuf_append rb_rawbuf_flush -rb_rawbuf_get rb_rawbuf_length rb_read rb_recv_fd_buf diff --git a/libratbox/src/gnutls.c b/libratbox/src/gnutls.c index afd7a80d..51c99617 100644 --- a/libratbox/src/gnutls.c +++ b/libratbox/src/gnutls.c @@ -292,7 +292,7 @@ rb_load_file_into_datum_t(const char *file) FILE *f; gnutls_datum_t *datum; struct stat fileinfo; - if((f = fopen(file, "r")) == NULL) + if((f = fopen(file, "re")) == NULL) return NULL; if(fstat(fileno(f), &fileinfo)) return NULL; diff --git a/libratbox/src/openssl.c b/libratbox/src/openssl.c index 49cb51f5..d44f7d5b 100644 --- a/libratbox/src/openssl.c +++ b/libratbox/src/openssl.c @@ -195,36 +195,6 @@ rb_ssl_tryaccept(rb_fde_t *F, void *data) } -static void -rb_ssl_accept_common(rb_fde_t *new_F) -{ - int ssl_err; - if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0) - { - switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err)) - { - case SSL_ERROR_SYSCALL: - if(rb_ignore_errno(errno)) - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - { - new_F->sslerr.ssl_errno = get_last_err(); - rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE, - rb_ssl_tryaccept, NULL); - return; - } - default: - new_F->sslerr.ssl_errno = get_last_err(); - new_F->accept->callback(new_F, RB_ERROR_SSL, NULL, 0, new_F->accept->data); - return; - } - } - else - { - rb_ssl_tryaccept(new_F, NULL); - } -} - void rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout) { @@ -250,7 +220,7 @@ rb_ssl_start_accepted(rb_fde_t *new_F, ACCB * cb, void *data, int timeout) new_F->accept->addrlen = 0; SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F)); rb_setup_ssl_cb(new_F); - rb_ssl_accept_common(new_F); + rb_ssl_tryaccept(new_F, NULL); } @@ -285,7 +255,7 @@ rb_ssl_accept_setup(rb_fde_t *F, rb_fde_t *new_F, struct sockaddr *st, rb_sockle SSL_set_fd((SSL *) new_F->ssl, rb_get_fd(new_F)); rb_setup_ssl_cb(new_F); - rb_ssl_accept_common(new_F); + rb_ssl_tryaccept(new_F, NULL); } typedef enum { @@ -492,6 +462,17 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c #endif #ifdef SSL_OP_NO_TLSv1_1 tls_opts |= SSL_OP_NO_TLSv1_1; +#endif + break; + case RB_TLS_VER_TLS1_3: +#ifdef SSL_OP_NO_TLSv1 + tls_opts |= SSL_OP_NO_TLSv1; +#endif +#ifdef SSL_OP_NO_TLSv1_1 + tls_opts |= SSL_OP_NO_TLSv1_1; +#endif +#ifdef SSL_OP_NO_TLSv1_2 + tls_opts |= SSL_OP_NO_TLSv1_2; #endif break; case RB_TLS_VER_LAST: @@ -558,7 +539,7 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c if(dhfile != NULL) { /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */ - BIO *bio = BIO_new_file(dhfile, "r"); + BIO *bio = BIO_new_file(dhfile, "re"); if(bio != NULL) { DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); diff --git a/libratbox/src/rawbuf.c b/libratbox/src/rawbuf.c index 25f3859b..8157777e 100644 --- a/libratbox/src/rawbuf.c +++ b/libratbox/src/rawbuf.c @@ -28,8 +28,9 @@ struct _rb_rawbuf { rb_dlink_node node; - uint8_t data[RAWBUF_SIZE]; + void *data; size_t len; + size_t written; bool flushing; }; @@ -37,7 +38,6 @@ struct _rb_rawbuf_head { rb_dlink_list list; size_t len; - size_t written; }; @@ -55,6 +55,9 @@ static void rb_rawbuf_done(rb_rawbuf_head_t * rb, rb_rawbuf_t * buf) { rb_rawbuf_t *ptr = buf; + if(buf->data != NULL) + rb_free(buf->data); + rb_dlinkDelete(&buf->node, &rb->list); rb_free(ptr); } @@ -83,8 +86,8 @@ rb_rawbuf_flush_writev(rb_rawbuf_head_t * rb, rb_fde_t *F) buf = ptr->data; if(buf->flushing == true) { - vec[x].iov_base = buf->data + rb->written; - vec[x++].iov_len = buf->len - rb->written; + vec[x].iov_base = buf->data + buf->written; + vec[x++].iov_len = buf->len - buf->written; continue; } vec[x].iov_base = buf->data; @@ -108,10 +111,10 @@ rb_rawbuf_flush_writev(rb_rawbuf_head_t * rb, rb_fde_t *F) break; if(buf->flushing == true) { - if(xret >= (ssize_t)(buf->len - rb->written)) + if(xret >= (ssize_t)(buf->len - buf->written)) { - xret -= buf->len - rb->written; - rb->len -= buf->len - rb->written; + xret -= buf->len - buf->written; + rb->len -= buf->len - buf->written; rb_rawbuf_done(rb, buf); continue; } @@ -126,7 +129,7 @@ rb_rawbuf_flush_writev(rb_rawbuf_head_t * rb, rb_fde_t *F) else { buf->flushing = true; - rb->written = (size_t)xret; + buf->written = (size_t)xret; rb->len -= (size_t)xret; break; } @@ -140,6 +143,7 @@ rb_rawbuf_flush(rb_rawbuf_head_t * rb, rb_fde_t *F) { rb_rawbuf_t *buf; ssize_t retval; + if(rb->list.head == NULL) { errno = EAGAIN; @@ -153,19 +157,17 @@ rb_rawbuf_flush(rb_rawbuf_head_t * rb, rb_fde_t *F) if(buf->flushing == false) { buf->flushing = true; - rb->written = 0; + buf->written = 0; } - retval = rb_write(F, buf->data + rb->written, buf->len - rb->written); + retval = rb_write(F, buf->data + buf->written, buf->len - buf->written); if(retval <= 0) return retval; - rb->written += (size_t)retval; - if(rb->written == buf->len) + buf->written += (size_t)retval; + if(buf->written == buf->len) { - rb->written = 0; - rb_dlinkDelete(&buf->node, &rb->list); - rb_free(buf); + rb_rawbuf_done(rb, buf); } rb->len -= (size_t)retval; return retval; @@ -178,38 +180,16 @@ rb_rawbuf_flush(rb_rawbuf_head_t * rb, rb_fde_t *F) void rb_rawbuf_append(rb_rawbuf_head_t * rb, void *in, size_t len) { - rb_rawbuf_t *buf = NULL; - size_t clen; - void *ptr; - uint8_t *data = in; - - if(rb->list.tail != NULL) - buf = rb->list.tail->data; - - if(buf != NULL && buf->len < sizeof(buf->data) && buf->flushing == false) - { - ptr = (void *)((uintptr_t)buf->data + buf->len); - clen = IRCD_MIN((sizeof(buf->data) - buf->len), len); - memcpy(ptr, data, clen); - buf->len += clen; - rb->len += clen; - len -= clen; - data = (data + clen); - } - - while(len > 0) - { - buf = rb_rawbuf_newbuf(rb); - clen = IRCD_MIN(sizeof(buf->data), len); - memcpy(buf->data, data, clen); - buf->len += clen; - rb->len += clen; - len -= clen; - data = (data + clen); - } + rb_rawbuf_t *buf; + buf = rb_rawbuf_newbuf(rb); + buf->data = rb_malloc(len); + buf->len = len; + memcpy(buf->data, in, len); + rb->len += buf->len; } - +#if 0 +/* this is still broken..if somebody wants to use it, they need to fix it */ size_t rb_rawbuf_get(rb_rawbuf_head_t * rb, void *data, size_t len) { @@ -222,31 +202,29 @@ rb_rawbuf_get(rb_rawbuf_head_t * rb, void *data, size_t len) buf = rb->list.head->data; if(buf->flushing == true) - ptr = (void *)(buf->data + rb->written); + ptr = (void *)(buf->data + buf->written); else ptr = buf->data; - if(len > buf->len) - cpylen = buf->len; - else - cpylen = len; + cpylen = IRCD_MIN(len, buf->len); memcpy(data, ptr, cpylen); if(cpylen == buf->len) { - rb->written = 0; + buf->written = 0; rb_rawbuf_done(rb, buf); - rb->len -= len; + rb->len -= cpylen; return cpylen; } buf->flushing = true; buf->len -= cpylen; rb->len -= cpylen; - rb->written += cpylen; + buf->written += cpylen; return cpylen; } +#endif size_t rb_rawbuf_length(rb_rawbuf_head_t * rb) diff --git a/libratbox/src/unix.c b/libratbox/src/unix.c index 840fa2ea..7e84616a 100644 --- a/libratbox/src/unix.c +++ b/libratbox/src/unix.c @@ -41,6 +41,7 @@ extern char **environ; pid_t rb_spawn_process(const char *path, const char **argv) { + int ret; pid_t pid; const void *arghack = argv; char **myenviron; @@ -54,11 +55,13 @@ rb_spawn_process(const char *path, const char **argv) #else myenviron = environ; #endif - if(posix_spawn(&pid, path, NULL, &spattr, arghack, myenviron)) - { + ret = posix_spawn(&pid, path, NULL, &spattr, arghack, myenviron); + posix_spawnattr_destroy(&spattr); + + if(ret) return -1; - } - return pid; + else + return pid; } #else pid_t diff --git a/modules/m_kline.c b/modules/m_kline.c index c284216e..dbfbf615 100644 --- a/modules/m_kline.c +++ b/modules/m_kline.c @@ -81,7 +81,7 @@ mapi_clist_av1 kline_clist[] = { &kline_msgtab, &unkline_msgtab, &adminkline_msg DECLARE_MODULE_AV1(kline, NULL, NULL, kline_clist, NULL, NULL, "$Revision$"); /* Local function prototypes */ -static int find_user_host(struct Client *source_p, const char *userhost, char *user, char *host); +static int find_user_host(struct Client *source_p, const char *userhost, char *user, size_t usersz, char *host, size_t hostsz); static int valid_user_host(struct Client *source_p, const char *user, const char *host); static int valid_wild_card(struct Client *source_p, const char *user, const char *host); @@ -127,7 +127,7 @@ mo_kline(struct Client *client_p, struct Client *source_p, int parc, const char else tkline_time = 0; - if(find_user_host(source_p, parv[loc], user, host) == 0) + if(find_user_host(source_p, parv[loc], user, sizeof(user), host, sizeof(host)) == 0) return 0; loc++; @@ -216,7 +216,7 @@ mo_adminkline(struct Client *client_p, struct Client *source_p, int parc, const return 0; } - if(find_user_host(source_p, parv[1], user, host) == 0) + if(find_user_host(source_p, parv[1], user, sizeof(user), host, sizeof(host)) == 0) return 0; set_kline(source_p, user, host, parv[2], 0, 1); @@ -523,10 +523,11 @@ mangle_wildcard_to_cidr(const char *text) * side effects - */ static int -find_user_host(struct Client *source_p, const char *userhost, char *luser, char *lhost) +find_user_host(struct Client *source_p, const char *uh, char *luser, size_t lusersz, char *lhost, size_t lhostsz) { char *hostp; const char *ptr; + char *userhost = LOCAL_COPY(uh); hostp = strchr(userhost, '@'); @@ -534,18 +535,18 @@ find_user_host(struct Client *source_p, const char *userhost, char *luser, char { *(hostp++) = '\0'; /* short and squat */ if(*userhost) - rb_strlcpy(luser, userhost, USERLEN + 1); /* here is my user */ + rb_strlcpy(luser, userhost, lusersz); /* here is my user */ else - strcpy(luser, "*"); + rb_strlcpy(luser, "*", lusersz); if(*hostp) { ptr = mangle_wildcard_to_cidr(hostp); if(ptr == NULL) ptr = hostp; - rb_strlcpy(lhost, ptr, HOSTLEN + 1); /* here is my host */ + rb_strlcpy(lhost, ptr, lhostsz); /* here is my host */ } else - strcpy(lhost, "*"); + rb_strlcpy(lhost, "*", lhostsz); } else { @@ -558,14 +559,13 @@ find_user_host(struct Client *source_p, const char *userhost, char *luser, char return 0; } - luser[0] = '*'; /* no @ found, assume its *@somehost */ - luser[1] = '\0'; + rb_strlcpy(luser, "*", lusersz); /* no @ found, assume its *@somehost */ ptr = mangle_wildcard_to_cidr(userhost); if(ptr == NULL) ptr = userhost; - rb_strlcpy(lhost, ptr, HOSTLEN + 1); + rb_strlcpy(lhost, ptr, lhostsz); } return 1; diff --git a/modules/m_whois.c b/modules/m_whois.c index 1f6a0769..1aa718e5 100644 --- a/modules/m_whois.c +++ b/modules/m_whois.c @@ -182,7 +182,7 @@ do_whois(struct Client *client_p, struct Client *source_p, int parc, const char int operspy = 0; nick = LOCAL_COPY(parv[1]); - if((p = strchr(parv[1], ','))) + if((p = strchr(nick, ','))) *p = '\0'; if(IsOperSpy(source_p) && *nick == '!') diff --git a/modules/m_whowas.c b/modules/m_whowas.c index ff533e7b..55c5d6ae 100644 --- a/modules/m_whowas.c +++ b/modules/m_whowas.c @@ -90,18 +90,16 @@ m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char return 0; #endif - if((p = strchr(parv[1], ','))) + nick = LOCAL_COPY(parv[1]); + if((p = strchr(nick, ','))) *p = '\0'; - nick = parv[1]; - - whowas_list = whowas_get_list(nick); if(whowas_list == NULL) { sendto_one_numeric(source_p, s_RPL(ERR_WASNOSUCHNICK), nick); - sendto_one_numeric(source_p, s_RPL(RPL_ENDOFWHOWAS), parv[1]); + sendto_one_numeric(source_p, s_RPL(RPL_ENDOFWHOWAS), nick); return 0; } @@ -130,6 +128,6 @@ m_whowas(struct Client *client_p, struct Client *source_p, int parc, const char if(max > 0 && cur >= max) break; } - sendto_one_numeric(source_p, s_RPL(RPL_ENDOFWHOWAS), parv[1]); + sendto_one_numeric(source_p, s_RPL(RPL_ENDOFWHOWAS), nick); return 0; } diff --git a/resolver/res.c b/resolver/res.c index 4acfadfc..c4bde9e1 100644 --- a/resolver/res.c +++ b/resolver/res.c @@ -588,13 +588,13 @@ do_query_number(struct DNSQuery *query, const struct rb_sockaddr_storage *addr, static void query_name(struct reslist *request) { - void *buf = alloca(MAXPACKET); + char buf[MAXPACKET]; int request_len = 0; - memset(buf, 0, MAXPACKET); + memset(buf, 0, sizeof(buf)); if((request_len = - irc_res_mkquery(request->queryname, C_IN, request->type, buf, MAXPACKET)) > 0) + irc_res_mkquery(request->queryname, C_IN, request->type, buf, sizeof(buf))) > 0) { HEADER *header = (HEADER *) buf; /* @@ -799,8 +799,7 @@ proc_answer(struct reslist *request, HEADER * header, char *buf, char *eob) static int res_read_single_reply(rb_fde_t *F, void *data) { - int buflen = sizeof(HEADER) + MAXPACKET; - void *buf = alloca(buflen); + char buf[sizeof(HEADER) + MAXPACKET]; HEADER *header; struct reslist *request = NULL; @@ -810,7 +809,7 @@ res_read_single_reply(rb_fde_t *F, void *data) rb_socklen_t len = sizeof(struct rb_sockaddr_storage); struct rb_sockaddr_storage lsin; - rc = recvfrom(rb_get_fd(F), buf, buflen, 0, (struct sockaddr *)&lsin, &len); + rc = recvfrom(rb_get_fd(F), buf, sizeof(buf), 0, (struct sockaddr *)&lsin, &len); /* No packet */ if(rc == 0 || rc == -1) diff --git a/src/cache.c b/src/cache.c index fd98d1c9..cacf242a 100644 --- a/src/cache.c +++ b/src/cache.c @@ -347,7 +347,10 @@ cache_user_motd(void) struct stat sb; struct tm *local_tm; - if(stat(MPATH, &sb) == 0) + if(ConfigFileEntry.motd_path == NULL) + return; + + if(stat(ConfigFileEntry.motd_path, &sb) == 0) { local_tm = gmtime(&sb.st_mtime); @@ -367,6 +370,8 @@ cache_user_motd(void) void cache_oper_motd(void) { + if(ConfigFileEntry.oper_motd_path == NULL) + return; free_cachefile(oper_motd); oper_motd = cache_file(ConfigFileEntry.oper_motd_path, "oper.motd", 0); } diff --git a/src/dns.c b/src/dns.c index 8c47d539..b018ab36 100644 --- a/src/dns.c +++ b/src/dns.c @@ -32,12 +32,11 @@ #include "send.h" #include "numeric.h" -#define DNS_IDTABLE_SIZE 0x2000 #define DNS_HOST ((char)'H') #define DNS_REVERSE ((char)'I') -static void submit_dns(const char, uint16_t id, int aftype, const char *addr); +static void submit_dns(const char, uint32_t id, int aftype, const char *addr); static int start_resolver(void); static void parse_dns_reply(rb_helper * helper); static void restart_resolver_cb(rb_helper * helper); @@ -46,31 +45,68 @@ static rb_helper *dns_helper; struct dnsreq { + rb_dlink_node node; DNSCB *callback; void *data; + uint32_t id; + uint32_t hashv; }; -static struct dnsreq querytable[DNS_IDTABLE_SIZE]; -static uint16_t -assign_dns_id(void) +#define RB_DNS_HASH_BITS 12 +#define RB_DNS_HASH_SIZE (1UL << RB_DNS_HASH_BITS) +#define RB_DNS_HASH_MASK (RB_DNS_HASH_SIZE-1) + + +#define rb_hash_dns(x) (((unsigned long)x ^ ((unsigned long)x >> RB_DNS_HASH_BITS) ^ ((unsigned long)x >> (RB_DNS_HASH_BITS * 2))) & RB_DNS_HASH_MASK) + + +static rb_dlink_list query_hash[RB_DNS_HASH_SIZE]; + + +static __rb_must_check struct dnsreq * +get_request_from_id(uint32_t id) { - static uint16_t id = 1; - int loopcnt = 0; - while(1) - { - if(++loopcnt > DNS_IDTABLE_SIZE) - return 0; - if(id < DNS_IDTABLE_SIZE - 1 || id == 0) - id++; - else - id = 1; - if(querytable[id].callback == NULL) - break; - } - return (id); + struct dnsreq *req; + rb_dlink_list *hlist; + rb_dlink_node *ptr; + + hlist = &query_hash[rb_hash_dns(id)]; + + if(hlist->head == NULL) + return NULL; + + RB_DLINK_FOREACH(ptr, hlist->head) + { + req = ptr->data; + if(req->id == id) + return req; + } + return NULL; +} + + + +static struct dnsreq * +allocate_dns_request(DNSCB *cb, void *data) +{ + struct dnsreq *req; + static uint32_t id = 0; + + id++; + if(id == 0) + id++; + + req = rb_malloc(sizeof(struct dnsreq)); + req->id = id; + req->hashv = rb_hash_dns(id); + req->callback = cb; + req->data = data; + rb_dlinkAdd(req, &req->node, &query_hash[req->hashv]); + return req; } + static inline void check_resolver(void) { @@ -79,41 +115,49 @@ check_resolver(void) } static void -failed_resolver(uint16_t xid) +failed_resolver(uint32_t xid) { struct dnsreq *req; + DNSCB *cb; + void *data; + uint32_t hashv; + + req = get_request_from_id(xid); - req = &querytable[xid]; - if(req->callback == NULL) + if(req == NULL) return; - req->callback("FAILED", 0, 0, req->data); - req->callback = NULL; - req->data = NULL; + cb = req->callback; + data = req->data; + hashv = req->hashv; + + rb_dlinkDelete(&req->node, &query_hash[hashv]); + rb_free(req); + + if(cb != NULL) + cb("FAILED", 0, 0, data); + } void -cancel_lookup(uint16_t xid) +cancel_lookup(uint32_t xid) { - querytable[xid].callback = NULL; - querytable[xid].data = NULL; + struct dnsreq *req; + req = get_request_from_id(xid); + if(req == NULL) + return; + rb_dlinkDelete(&req->node, &query_hash[req->hashv]); + rb_free(req); } -uint16_t +uint32_t lookup_hostname(const char *hostname, int aftype, DNSCB * callback, void *data) { struct dnsreq *req; int aft; - uint16_t nid; check_resolver(); - if((nid = assign_dns_id()) == 0) - return 0; - - req = &querytable[nid]; - - req->callback = callback; - req->data = data; + req = allocate_dns_request(callback, data); #ifdef RB_IPV6 if(aftype == AF_INET6) @@ -122,25 +166,18 @@ lookup_hostname(const char *hostname, int aftype, DNSCB * callback, void *data) #endif aft = 4; - submit_dns(DNS_HOST, nid, aft, hostname); - return (nid); + submit_dns(DNS_HOST, req->id, aft, hostname); + return (req->id); } -uint16_t +uint32_t lookup_ip(const char *addr, int aftype, DNSCB * callback, void *data) { struct dnsreq *req; int aft; - uint16_t nid; check_resolver(); - if((nid = assign_dns_id()) == 0) - return 0; - - req = &querytable[nid]; - - req->callback = callback; - req->data = data; + req = allocate_dns_request(callback, data); #ifdef RB_IPV6 if(aftype == AF_INET6) @@ -149,41 +186,44 @@ lookup_ip(const char *addr, int aftype, DNSCB * callback, void *data) #endif aft = 4; - submit_dns(DNS_REVERSE, nid, aft, addr); - return (nid); + submit_dns(DNS_REVERSE, req->id, aft, addr); + return (req->id); } static void results_callback(const char *callid, const char *status, const char *aftype, const char *results) { + DNSCB *cb; + void *data; struct dnsreq *req; - uint16_t nid; + uint32_t nid; int st; int aft; - long lnid = strtol(callid, NULL, 16); - if(lnid > DNS_IDTABLE_SIZE || lnid == 0) + nid = strtoul(callid, 0, 16); + + req = get_request_from_id(nid); + if(req == NULL) return; - nid = (uint16_t)lnid; - req = &querytable[nid]; + st = atoi(status); aft = atoi(aftype); - if(req->callback == NULL) - { - /* got cancelled..oh well */ - req->data = NULL; - return; - } + #ifdef RB_IPV6 if(aft == 6) aft = AF_INET6; else #endif aft = AF_INET; + + cb = req->callback; + data = req->data; + + rb_dlinkDelete(&req->node, &query_hash[req->hashv]); + rb_free(req); - req->callback(results, st, aft, req->data); - req->callback = NULL; - req->data = NULL; + if(cb != NULL) + cb(results, st, aft, data); } @@ -301,7 +341,7 @@ parse_dns_reply(rb_helper * helper) } static void -submit_dns(char type, uint16_t nid, int aftype, const char *addr) +submit_dns(char type, uint32_t nid, int aftype, const char *addr) { if(dns_helper == NULL) { diff --git a/src/hash.c b/src/hash.c index ca057908..f17f34b3 100644 --- a/src/hash.c +++ b/src/hash.c @@ -422,13 +422,19 @@ hash_node * hash_add_len(hash_f *hf, const void *hashindex, size_t indexlen, void *pointer) { rb_dlink_list *bucket; // = hash_function[type].table; + size_t hashlen; hash_node *hnode; uint32_t hashv; if(hf == NULL || hashindex == NULL || pointer == NULL) return NULL; - hashv = do_hfunc(hf, hashindex, IRCD_MIN(indexlen, hf->hashlen)); + if(hf->hashlen == 0) + hashlen = indexlen; + else + hashlen = IRCD_MIN(indexlen, hf->hashlen); + + hashv = do_hfunc(hf, hashindex, hashlen); bucket = hash_allocate_bucket(hf, hashv); hnode = rb_malloc(sizeof(hash_node)); hnode->key = rb_malloc(indexlen); diff --git a/src/newconf.c b/src/newconf.c index 3df529f8..ce7c527d 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -1117,6 +1117,7 @@ static const char *ver_table[] = { [RB_TLS_VER_TLS1] = "tls1.0", [RB_TLS_VER_TLS1_1] = "tls1.1", [RB_TLS_VER_TLS1_2] = "tls1.2", + [RB_TLS_VER_TLS1_3] = "tls1.3", [RB_TLS_VER_LAST] = NULL, }; diff --git a/src/s_auth.c b/src/s_auth.c index 1b221c0d..94dffd7f 100644 --- a/src/s_auth.c +++ b/src/s_auth.c @@ -76,7 +76,7 @@ struct AuthRequest { rb_dlink_node node; struct Client *client; /* pointer to client struct for request */ - uint16_t dns_query; /* DNS Query */ + uint32_t dns_query; /* DNS Query */ rb_dlink_list rbl_queries; rb_fde_t *authF; unsigned int flags; /* current state of request */ diff --git a/ssld/ssld.c b/ssld/ssld.c index 7d826c6d..37144619 100644 --- a/ssld/ssld.c +++ b/ssld/ssld.c @@ -1236,11 +1236,53 @@ read_pipe_ctl(rb_fde_t *F, void *data) rb_setselect(F, RB_SELECT_READ, read_pipe_ctl, NULL); } +static void +check_control(int control_fd) +{ + struct sockaddr_in addr; + socklen_t len; + + if(control_fd < 0) + { + fprintf(stderr, "No control socket\n"); + exit(1); + } + + len = sizeof(addr); + if(getsockname(control_fd, (struct sockaddr *)&addr, &len) == -1) + { + fprintf(stderr, "Control descriptor is not a socket!\n"); + exit(1); + } + if(addr.sin_family != AF_UNIX) + { + fprintf(stderr, "Control descriptor is not a unix socket!\n"); + exit(1); + } +} + +static void +check_pipe(int pipefd) +{ + struct stat st; + + if(fstat(pipefd, &st) < 0) + { + fprintf(stderr, "No control pipe\n"); + exit(1); + } + if(!S_ISFIFO(st.st_mode)) + { + fprintf(stderr, "Control pipe is not a pipe\n"); + exit(1); + } +} + int main(int argc, char **argv) { const char *s_ctlfd, *s_pipe, *s_pid; - int ctlfd, pipefd, maxfd; + int ctlfd, pipefd, maxfd, x; mod_ctl_t *mod_ctl; maxfd = maxconn(); @@ -1260,7 +1302,8 @@ main(int argc, char **argv) pipefd = atoi(s_pipe); ppid = atoi(s_pid); - int x; + check_pipe(pipefd); + check_control(ctlfd); for(x = 0; x < maxfd; x++) {