From 07c2bb757d2b2096091e72b28454d62aa1dac0d0 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 7 Mar 2009 03:23:17 +0100 Subject: [PATCH] Fix close detection with ssl+zip, porting more code from ircd-ratbox. This tells the SSL ssld to report connection closure to ircd using the new fd. --- src/sslproc.c | 11 +++++++++++ ssld/ssld.c | 26 ++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/sslproc.c b/src/sslproc.c index e525af81..4789e86f 100644 --- a/src/sslproc.c +++ b/src/sslproc.c @@ -695,6 +695,7 @@ start_zlib_session(void *data) rb_fde_t *F[2]; rb_fde_t *xF1, *xF2; char *buf; + char buf2[9]; void *recvq_start; size_t hdr = (sizeof(uint8_t) * 2) + sizeof(int32_t); @@ -741,6 +742,16 @@ start_zlib_session(void *data) *buf = 'Z'; rb_socketpair(AF_UNIX, SOCK_STREAM, 0, &xF1, &xF2, "Initial zlib socketpairs"); + if(IsSSL(server)) + { + /* tell ssld the new connid for the ssl part*/ + buf2[0] = 'Y'; + int32_to_buf(&buf2[1], rb_get_fd(server->localClient->F)); + int32_to_buf(&buf2[5], rb_get_fd(xF2)); + ssl_cmd_write_queue(server->localClient->ssl_ctl, NULL, 0, buf2, sizeof(buf2)); + } + + F[0] = server->localClient->F; F[1] = xF1; del_from_cli_fd_hash(server); diff --git a/ssld/ssld.c b/ssld/ssld.c index 55da1dd4..ed44e99f 100644 --- a/ssld/ssld.c +++ b/ssld/ssld.c @@ -127,6 +127,7 @@ typedef struct _conn #define FLAG_DEAD 0x08 #define FLAG_SSL_W_WANTS_R 0x10 /* output needs to wait until input possible */ #define FLAG_SSL_R_WANTS_W 0x20 /* input needs to wait until output possible */ +#define FLAG_ZIPSSL 0x40 #define IsSSL(x) ((x)->flags & FLAG_SSL) #define IsZip(x) ((x)->flags & FLAG_ZIP) @@ -134,6 +135,7 @@ typedef struct _conn #define IsDead(x) ((x)->flags & FLAG_DEAD) #define IsSSLWWantsR(x) ((x)->flags & FLAG_SSL_W_WANTS_R) #define IsSSLRWantsW(x) ((x)->flags & FLAG_SSL_R_WANTS_W) +#define IsZipSSL(x) ((x)->flags & FLAG_ZIPSSL) #define SetSSL(x) ((x)->flags |= FLAG_SSL) #define SetZip(x) ((x)->flags |= FLAG_ZIP) @@ -141,6 +143,7 @@ typedef struct _conn #define SetDead(x) ((x)->flags |= FLAG_DEAD) #define SetSSLWWantsR(x) ((x)->flags |= FLAG_SSL_W_WANTS_R) #define SetSSLRWantsW(x) ((x)->flags |= FLAG_SSL_R_WANTS_W) +#define SetZipSSL(x) ((x)->flags |= FLAG_ZIPSSL) #define ClearSSL(x) ((x)->flags &= ~FLAG_SSL) #define ClearZip(x) ((x)->flags &= ~FLAG_ZIP) @@ -148,6 +151,7 @@ typedef struct _conn #define ClearDead(x) ((x)->flags &= ~FLAG_DEAD) #define ClearSSLWWantsR(x) ((x)->flags &= ~FLAG_SSL_W_WANTS_R) #define ClearSSLRWantsW(x) ((x)->flags &= ~FLAG_SSL_R_WANTS_W) +#define ClearZipSSL(x) ((x)->flags &= ~FLAG_ZIPSSL) #define NO_WAIT 0x0 #define WAIT_PLAIN 0x1 @@ -262,7 +266,7 @@ close_conn(conn_t * conn, int wait_plain, const char *fmt, ...) { rb_close(conn->plain_fd); - if(conn->id >= 0) + if(conn->id >= 0 && !IsZipSSL(conn)) rb_dlinkDelete(&conn->node, connid_hash(conn->id)); rb_dlinkAdd(conn, &conn->node, &dead_list); return; @@ -750,6 +754,18 @@ process_stats(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb) mod_cmd_write_queue(ctl, outstat, strlen(outstat) + 1); /* +1 is so we send the \0 as well */ } +static void +change_connid(mod_ctl_t *ctl, mod_ctl_buf_t *ctlb) +{ + int32_t id = buf_to_int32(&ctlb->buf[1]); + int32_t newid = buf_to_int32(&ctlb->buf[5]); + conn_t *conn = conn_find_by_id(id); + if(conn->id >= 0) + rb_dlinkDelete(&conn->node, connid_hash(conn->id)); + SetZipSSL(conn); + conn->id = newid; +} + #ifdef HAVE_LIBZ static void zlib_process(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb) @@ -939,6 +955,12 @@ mod_process_cmd_recv(mod_ctl_t * ctl) process_stats(ctl, ctl_buf); break; } + case 'Y': + { + change_connid(ctl, ctl_buf); + break; + } + #ifdef HAVE_LIBZ case 'Z': { @@ -947,7 +969,7 @@ mod_process_cmd_recv(mod_ctl_t * ctl) break; } #else - case 'Y': + case 'Z': send_nozlib_support(ctl, ctl_buf); break;