Skip to content

Commit

Permalink
node: Use node's rfd and wfd instead of private ones.
Browse files Browse the repository at this point in the history
Many modules, particularly net modules, store the read
and write file descriptors on their private session struct.
At some point, these were added to the node struct itself,
making these redundant. Simplify rfd/wfd usage by just using
the node versions and eliminating any private versions.
  • Loading branch information
InterLinked1 committed Apr 9, 2024
1 parent b0f6318 commit 263e900
Show file tree
Hide file tree
Showing 16 changed files with 113 additions and 154 deletions.
11 changes: 6 additions & 5 deletions bbs/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,12 +661,13 @@ static int ssl_servername_cb(SSL *s, int *ad, void *arg)

SSL *ssl_node_new_accept(struct bbs_node *node, int *rfd, int *wfd)
{
SSL *ssl = ssl_new_accept(node, node->fd, rfd, wfd);
if (rfd) {
node->rfd = *rfd;
int my_rfd = -1, my_wfd = -1;
SSL *ssl = ssl_new_accept(node, node->fd, &my_rfd, &my_wfd);
if (my_rfd >= 0) {
*rfd = my_rfd;
}
if (wfd) {
node->wfd = *wfd;
if (my_wfd >= 0) {
*wfd = my_wfd;
}
return ssl;
}
Expand Down
2 changes: 0 additions & 2 deletions include/mod_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,6 @@ struct http_session {
struct bbs_node *node;
struct readline_data *rldata;
char *buf; /*!< Stack-allocated readline data buffer */
int rfd;
int wfd;
unsigned int secure:1;
};

Expand Down
42 changes: 20 additions & 22 deletions modules/mod_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ static unsigned short int proxy_port = 0;
static enum http_method proxy_methods = HTTP_METHOD_UNDEF;

#define http_send_header(http, fmt, ...) \
bbs_node_fd_writef(http->node, http->wfd, fmt, ## __VA_ARGS__); \
bbs_node_fd_writef(http->node, http->node->wfd, fmt, ## __VA_ARGS__); \
http_debug(5, "<= " fmt, ## __VA_ARGS__);

static const char *http_response_code_name(enum http_response_code code)
Expand Down Expand Up @@ -241,7 +241,7 @@ static void http_send_headers(struct http_session *http)
http_send_header(http, "%s: %s\r\n", key, value);
bbs_vars_remove_first(&http->res->headers);
}
NODE_SWRITE(http->node, http->wfd, "\r\n"); /* CR LF to indicate end of headers */
NODE_SWRITE(http->node, http->node->wfd, "\r\n"); /* CR LF to indicate end of headers */
}

int http_set_header(struct http_session *http, const char *header, const char *value)
Expand Down Expand Up @@ -301,7 +301,7 @@ static void __http_write(struct http_session *http, const char *buf, size_t len)
http_send_headers(http);
}

bbs_write(http->wfd, buf, len);
bbs_write(http->node->wfd, buf, len);
http->res->sentbytes += len;
}

Expand All @@ -314,7 +314,7 @@ static void send_chunk(struct http_session *http, const char *buf, size_t len)

http_send_header(http, "%x\r\n", (unsigned int) len); /* Doesn't count towards body length, so don't use __http_write */
__http_write(http, buf, len);
bbs_node_fd_writef(http->node, http->wfd, "\r\n"); /* Doesn't count towards length */
bbs_node_fd_writef(http->node, http->node->wfd, "\r\n"); /* Doesn't count towards length */
}

static void flush_buffer(struct http_session *http, int final)
Expand Down Expand Up @@ -355,9 +355,9 @@ static void flush_buffer(struct http_session *http, int final)
http->res->chunkedleft = sizeof(http->res->chunkbuf);
http->res->chunkedbytes = 0;
if (final) {
bbs_node_fd_writef(http->node, http->wfd, "0\r\n"); /* This is the beginning of the end. Optional footers may follow. */
bbs_node_fd_writef(http->node, http->node->wfd, "0\r\n"); /* This is the beginning of the end. Optional footers may follow. */
/* If we wanted to send optional footers, we could do so here. But we don't. */
bbs_node_fd_writef(http->node, http->wfd, "\r\n"); /* Very end of chunked transfer */
bbs_node_fd_writef(http->node, http->node->wfd, "\r\n"); /* Very end of chunked transfer */
}
}

Expand Down Expand Up @@ -946,7 +946,7 @@ static int read_body(struct http_session *http, char *buf, int discard)
for (;;) {
/* Determine how large the next chunk is */
unsigned int chunksize;
ssize_t res = bbs_readline(http->rfd, http->rldata, "\r\n", SEC_MS(10));
ssize_t res = bbs_readline(http->node->rfd, http->rldata, "\r\n", SEC_MS(10));
if (res <= 0) {
free_if(dynstr.buf);
bbs_warning("Failed to read all or part of chunked upload?\n");
Expand All @@ -958,17 +958,17 @@ static int read_body(struct http_session *http, char *buf, int discard)
break;
}
if (discard) {
bbs_readline_discard_n(http->rfd, http->rldata, SEC_MS(10), chunksize + 2); /* Read the bytes + trailing CR LF and throw them away */
bbs_readline_discard_n(http->node->rfd, http->rldata, SEC_MS(10), chunksize + 2); /* Read the bytes + trailing CR LF and throw them away */
} else {
bbs_readline_getn_dynstr(http->rfd, &dynstr, http->rldata, SEC_MS(10), chunksize);
bbs_readline_getn_dynstr(http->node->rfd, &dynstr, http->rldata, SEC_MS(10), chunksize);
bytes += (size_t) chunksize;
if (bytes >= MAX_HTTP_UPLOAD_SIZE) {
bbs_warning("Partial content length %lu is too large\n", http->req->contentlength);
free_if(dynstr.buf);
return 1;
}
/* Read and skip the trailing CR and LF after the chunk */
if (bbs_readline_getn_dynstr(http->rfd, &dynstr, http->rldata, SEC_MS(1), 2) != 2) {
if (bbs_readline_getn_dynstr(http->node->rfd, &dynstr, http->rldata, SEC_MS(1), 2) != 2) {
free_if(dynstr.buf);
return -1;
}
Expand All @@ -985,7 +985,7 @@ static int read_body(struct http_session *http, char *buf, int discard)

/* Read and discard any trailer entity-header lines, indicated by a blank line. */
for (;;) {
ssize_t res = bbs_readline(http->rfd, http->rldata, "\r\n", SEC_MS(5));
ssize_t res = bbs_readline(http->node->rfd, http->rldata, "\r\n", SEC_MS(5));
if (res < 0) {
return -1; /* At this point, http->req->body is cleaned up on exit so we don't need to free it here */
} else if (res == 0) {
Expand All @@ -1001,9 +1001,9 @@ static int read_body(struct http_session *http, char *buf, int discard)
if (discard) {
/* Read the data but don't bother saving it.
* We only do this so we can keep the connection alive. Otherwise we'd have to close it if we don't read the entire request. */
bbs_readline_discard_n(http->rfd, http->rldata, SEC_MS(10), http->req->contentlength); /* Read the bytes and throw them away */
bbs_readline_discard_n(http->node->rfd, http->rldata, SEC_MS(10), http->req->contentlength); /* Read the bytes and throw them away */
} else {
http->req->body = (unsigned char*) bbs_readline_getn_str(http->rfd, http->rldata, SEC_MS(10), http->req->contentlength);
http->req->body = (unsigned char*) bbs_readline_getn_str(http->node->rfd, http->rldata, SEC_MS(10), http->req->contentlength);
if (!http->req->body) {
return -1;
}
Expand Down Expand Up @@ -1676,7 +1676,7 @@ int http_parse_request(struct http_session *http, char *buf)
/* Particular consideration has been made of items discussed here: https://www.jmarshall.com/easy/http/ */

/* Read and parse the request line */
res = bbs_readline(http->rfd, http->rldata, "\r\n", SEC_MS(15));
res = bbs_readline(http->node->rfd, http->rldata, "\r\n", SEC_MS(15));
if (res <= 0) {
http->req->keepalive = 0;
http->res->code = HTTP_REQUEST_TIMEOUT;
Expand All @@ -1696,7 +1696,7 @@ int http_parse_request(struct http_session *http, char *buf)
/* Read and store headers */
for (;;) {
char *tmp;
res = bbs_readline(http->rfd, http->rldata, "\r\n", MIN_MS(1));
res = bbs_readline(http->node->rfd, http->rldata, "\r\n", MIN_MS(1));
if (res < 0) {
return -1;
} else if (res == 0) { /* CR LF = end of headers */
Expand Down Expand Up @@ -1821,7 +1821,7 @@ static int http_handle_request(struct http_session *http, char *buf)
/* Send a 100 Continue intermediate response if we're good so far. */
http->res->sent100 = 1;
http_send_header(http, "HTTP/1.1 100 Continue\r\n");
bbs_node_fd_writef(http->node, http->wfd, "\r\n");
bbs_node_fd_writef(http->node, http->node->wfd, "\r\n");
/* XXX If libcurl gets a 100 followed by a 404, it will be very unhappy (it will hang forever). */
}

Expand Down Expand Up @@ -1888,12 +1888,10 @@ static void http_handler(struct bbs_node *node, int secure)

/* Start TLS if we need to */
if (secure) {
ssl = ssl_node_new_accept(node, &http.rfd, &http.wfd);
ssl = ssl_node_new_accept(node, &http.node->rfd, &http.node->wfd);
if (!ssl) {
return; /* Disconnect. */
}
} else {
http.rfd = http.wfd = node->fd;
}

bbs_readline_init(&rldata, buf, sizeof(buf));
Expand Down Expand Up @@ -2289,7 +2287,7 @@ enum http_response_code http_static(struct http_session *http, const char *filen
if (ranges) {
if (rangeparts == 1) {
offset = a;
written = bbs_sendfile(http->wfd, fd, &offset, rangebytes);
written = bbs_sendfile(http->node->wfd, fd, &offset, rangebytes);
close(fd);
if (written != (ssize_t) rangebytes) {
http->req->keepalive = 0;
Expand All @@ -2306,7 +2304,7 @@ enum http_response_code http_static(struct http_session *http, const char *filen
http_writef(http, "\r\n");
offset = a;
bbs_debug(5, "Sending %ld-byte range beginning at offset %lu\n", thisrangebytes, offset);
written = bbs_sendfile(http->wfd, fd, &offset, (size_t) thisrangebytes);
written = bbs_sendfile(http->node->wfd, fd, &offset, (size_t) thisrangebytes);
if (written != (ssize_t) thisrangebytes) {
close(fd);
http->req->keepalive = 0;
Expand All @@ -2319,7 +2317,7 @@ enum http_response_code http_static(struct http_session *http, const char *filen
http_writef(http, "--%s--", RANGE_SEPARATOR); /* Final multipart boundary */
}
} else {
written = bbs_sendfile(http->wfd, fd, &offset, (size_t) st->st_size);
written = bbs_sendfile(http->node->wfd, fd, &offset, (size_t) st->st_size);
close(fd);
if (written != (ssize_t) st->st_size) {
http->req->keepalive = 0;
Expand Down
2 changes: 1 addition & 1 deletion modules/mod_http_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ static enum http_response_code proxy_handler(struct http_session *http)
/* For CONNECT, this is it, we can just send 200 OK now and then relay everything hereafter. */
http->res->code = HTTP_OK; /* Hasn't been set using the higher-level functions, so set manually */
http_send_response_status(http, HTTP_OK);
NODE_SWRITE(http->node, http->wfd, "\r\n"); /* CR LF to indicate end of headers */
NODE_SWRITE(http->node, http->node->wfd, "\r\n"); /* CR LF to indicate end of headers */
} else {
if (proxy_forward_headers(http, &client)) {
bbs_warning("Failed to forward headers to proxy destination %s:%u\n", host, port);
Expand Down
20 changes: 10 additions & 10 deletions nets/net_finger.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static void *finger_handler(void *varg)
* The /W modifier increases verbosity. */

/* This is not buffered since there's no pseudoterminal. */
res = bbs_poll_read(node->fd, 1000, buf, sizeof(buf) - 1);
res = bbs_poll_read(node->rfd, 1000, buf, sizeof(buf) - 1);
if (res <= 0) {
goto cleanup;
}
Expand Down Expand Up @@ -158,36 +158,36 @@ static void *finger_handler(void *varg)
}

if (!strlen_zero(username)) {
if (bbs_user_dump(node->fd, username, 4)) {
if (bbs_user_dump(node->wfd, username, 4)) {
bbs_debug(1, "No such user: %s\n", username);
} else {
char pfile[256];
unsigned int userid;
/* If user exists, also display project and plan, if available */
userid = bbs_userid_from_username(username);
if (!bbs_transfer_home_config_file(userid, ".project", pfile, sizeof(pfile))) {
bbs_node_fd_writef(node, node->fd, "Project: ");
if (print_file(node->fd, pfile, "\r\n", 1, 128)) {
bbs_node_fd_writef(node, node->wfd, "Project: ");
if (print_file(node->wfd, pfile, "\r\n", 1, 128)) {
/* If it failed, add a new line ourselves. */
bbs_node_fd_writef(node, node->fd, "\r\n");
bbs_node_fd_writef(node, node->wfd, "\r\n");
}
}
if (!bbs_transfer_home_config_file(userid, ".plan", pfile, sizeof(pfile))) {
/* If the user wants the plan to begin on its own line,
* then the first line of the plan can simply be a line break. */
bbs_node_fd_writef(node, node->fd, "Plan: ");
print_file(node->fd, pfile, "\r\n", 10, 512);
bbs_node_fd_writef(node, node->wfd, "Plan: ");
print_file(node->wfd, pfile, "\r\n", 10, 512);
/* Don't really care if there's a line break here or not */
} else {
bbs_node_fd_writef(node, node->fd, "No Plan.\r\n");
bbs_node_fd_writef(node, node->wfd, "No Plan.\r\n");
}
}
} else {
/* All users */
if (!allusersallowed) {
bbs_node_fd_writef(node, node->fd, "Finger online user list denied\r\n"); /* Other finger servers don't seem to do this, but the RFC says to... */
bbs_node_fd_writef(node, node->wfd, "Finger online user list denied\r\n"); /* Other finger servers don't seem to do this, but the RFC says to... */
} else {
bbs_users_dump(node->fd, 4);
bbs_users_dump(node->wfd, 4);
}
}

Expand Down
17 changes: 6 additions & 11 deletions nets/net_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ static int ftps_enabled = 0;
static int require_reuse = 0;

/*! \note Uses a statement expression so that we can also log all FTP responses */
#define ftp_write(ftp, code, fmt, ...) ({ bbs_debug(5, "FTP <= %d " fmt, code, ## __VA_ARGS__); bbs_writef(ftp->wfd, "%d " fmt, code, ## __VA_ARGS__); })
#define ftp_write0(ftp, code, fmt, ...) ({ bbs_debug(5, "FTP <= %d-" fmt, code, ## __VA_ARGS__); bbs_writef(ftp->wfd, "%d-" fmt, code, ## __VA_ARGS__); })
#define ftp_write_raw(ftp, fmt, ...) ({ bbs_debug(5, "FTP <= " fmt, ## __VA_ARGS__); bbs_writef(ftp->wfd, fmt, ## __VA_ARGS__); })
#define ftp_write(ftp, code, fmt, ...) ({ bbs_debug(5, "FTP <= %d " fmt, code, ## __VA_ARGS__); bbs_writef(ftp->node->wfd, "%d " fmt, code, ## __VA_ARGS__); })
#define ftp_write0(ftp, code, fmt, ...) ({ bbs_debug(5, "FTP <= %d-" fmt, code, ## __VA_ARGS__); bbs_writef(ftp->node->wfd, "%d-" fmt, code, ## __VA_ARGS__); })
#define ftp_write_raw(ftp, fmt, ...) ({ bbs_debug(5, "FTP <= " fmt, ## __VA_ARGS__); bbs_writef(ftp->node->wfd, fmt, ## __VA_ARGS__); })
#define ftp_write_raw2(ftp, fmt, ...) ({ bbs_debug(5, "FTP <= " fmt, ## __VA_ARGS__); bbs_writef(ftp->wfd2, fmt, ## __VA_ARGS__); })
#define IO_ABORT(res) if (res <= 0) { goto cleanup; }

Expand All @@ -76,9 +76,6 @@ static int require_reuse = 0;
}

struct ftp_session {
/* Control */
int rfd;
int wfd;
/* Data */
int rfd2;
int wfd2;
Expand Down Expand Up @@ -303,12 +300,10 @@ static void *ftp_handler(void *varg)

/* Start TLS if we need to */
if (!strcmp(node->protname, "FTPS")) {
ssl = ssl_node_new_accept(node, &ftp->rfd, &ftp->wfd);
ssl = ssl_node_new_accept(node, &ftp->node->rfd, &ftp->node->wfd);
if (!ssl) {
goto cleanup;
}
} else {
ftp->rfd = ftp->wfd = node->fd;
}

/* FTP uses CR LF line endings (but that's what you expected, right?) */
Expand All @@ -322,7 +317,7 @@ static void *ftp_handler(void *varg)

for (;;) {
next = NULL;
res = bbs_readline(ftp->rfd, &rldata, "\r\n", node->user ? bbs_transfer_timeout() : SEC_MS(15)); /* After some number of seconds of inactivity, a client times out */
res = bbs_readline(ftp->node->rfd, &rldata, "\r\n", node->user ? bbs_transfer_timeout() : SEC_MS(15)); /* After some number of seconds of inactivity, a client times out */
if (res <= 0) {
break;
}
Expand Down Expand Up @@ -409,7 +404,7 @@ static void *ftp_handler(void *varg)
/* AUTH TLS / AUTH SSL = RFC2228 opportunistic encryption */
if (!ssl && ssl_available()) {
res = ftp_write(ftp, 234, "Begin TLS negotiation\r\n");
ssl = ssl_node_new_accept(node, &ftp->rfd, &ftp->wfd);
ssl = ssl_node_new_accept(node, &ftp->node->rfd, &ftp->node->wfd);
if (!ssl) {
break; /* Just abort */
}
Expand Down
19 changes: 7 additions & 12 deletions nets/net_imap.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ static void __imap_send_update_log(struct imap_session *imap, const char *s, siz
}
} else {
imap_debug(4, "%d: %p <= %s", line, imap, s); /* Already ends in CR LF */
bbs_node_any_fd_write(imap->node, imap->wfd, s, (unsigned int) len);
bbs_node_any_fd_write(imap->node, imap->node->wfd, s, (unsigned int) len);
}
}

Expand Down Expand Up @@ -2405,7 +2405,7 @@ static int handle_append(struct imap_session *imap, char *s)
* If it's a MULTIAPPEND, we read another line.
* If we read an empty line (just CR LF), then that's the end of the APPEND operation. */
bbs_debug(7, "%d message%s appended so far, will there be more?\n", appends, ESS(appends));
res = bbs_readline(imap->rfd, imap->rldata, "\r\n", 5000);
res = bbs_readline(imap->node->rfd, imap->rldata, "\r\n", 5000);
if (res == 0 || res == -1) { /* either CR LF read or socket closed */
bbs_debug(3, "%d message%s appended successfully\n", appends, ESS(appends));
break;
Expand Down Expand Up @@ -2478,7 +2478,7 @@ static int handle_append(struct imap_session *imap, char *s)
* This is to avoid leaving the message in the buffer and trying to parse it all as IMAP commands,
* which would result in spamming the logs, and also present a security risk if any of the lines in the message
* is a potentially valid IMAP command. */
bbs_readline_discard_n(imap->rfd, imap->rldata, SEC_MS(10), (size_t) (appendsize + 2)); /* Read the bytes + trailing CR LF and throw them away */
bbs_readline_discard_n(imap->node->rfd, imap->rldata, SEC_MS(10), (size_t) (appendsize + 2)); /* Read the bytes + trailing CR LF and throw them away */
bbs_debug(5, "Discarded %d bytes\n", appendsize);
/* This is obviously wasteful of bandwidth. Client should've supported the APPENDLIMIT extension, though,
* so I'm not sympathetic. Get with the program already, know your limits! */
Expand All @@ -2493,7 +2493,7 @@ static int handle_append(struct imap_session *imap, char *s)
}
} else if ((unsigned long) appendsize >= quotaleft) {
if (!synchronizing) {
bbs_readline_discard_n(imap->rfd, imap->rldata, SEC_MS(10), (size_t) (appendsize + 2));
bbs_readline_discard_n(imap->node->rfd, imap->rldata, SEC_MS(10), (size_t) (appendsize + 2));
bbs_debug(5, "Discarded %d bytes\n", appendsize + 2);
imap_reply(imap, "NO [OVERQUOTA] Insufficient quota remaining");
continue;
Expand All @@ -2511,7 +2511,7 @@ static int handle_append(struct imap_session *imap, char *s)
if (synchronizing) {
_imap_reply(imap, "+ Ready for literal data\r\n"); /* Synchronizing literal response */
}
res = bbs_readline_getn(imap->rfd, appendfile, imap->rldata, 5000, (size_t) appendsize);
res = bbs_readline_getn(imap->node->rfd, appendfile, imap->rldata, 5000, (size_t) appendsize);
if (res != appendsize) {
bbs_warning("Client wanted to append %d bytes, but sent %lu?\n", appendsize, res);
close(appendfile);
Expand Down Expand Up @@ -4626,7 +4626,7 @@ static void handle_client(struct imap_session *imap)
for (;;) {
const char *word2;
/* Autologout timer should not be less than 30 minutes, according to the RFC. We'll uphold that, for clients that are logged in. */
ssize_t res = bbs_readline(imap->rfd, &rldata, "\r\n", bbs_user_is_registered(imap->node->user) ? MIN_MS(30) : MIN_MS(1));
ssize_t res = bbs_readline(imap->node->rfd, &rldata, "\r\n", bbs_user_is_registered(imap->node->user) ? MIN_MS(30) : MIN_MS(1));
if (res < 0) {
res += 1; /* Convert the res back to a normal one. */
if (res == 0) {
Expand All @@ -4653,22 +4653,17 @@ static void imap_handler(struct bbs_node *node, int secure)
#ifdef HAVE_OPENSSL
SSL *ssl;
#endif
int rfd, wfd;
struct imap_session imap, *s;

/* Start TLS if we need to */
if (secure) {
ssl = ssl_node_new_accept(node, &rfd, &wfd);
ssl = ssl_node_new_accept(node, &node->rfd, &node->wfd);
if (!ssl) {
return;
}
} else {
rfd = wfd = node->fd;
}

memset(&imap, 0, sizeof(imap));
imap.rfd = rfd;
imap.wfd = wfd;
imap.node = node;
RWLIST_HEAD_INIT(&imap.remotemailboxes);

Expand Down
Loading

0 comments on commit 263e900

Please sign in to comment.