From: Egor Date: Fri, 13 Jun 2025 03:08:19 +0000 (+0300) Subject: net: recvProc clean up X-Git-Url: https://git.patchysicp.xyz/?a=commitdiff_plain;h=ee63079a129374ba8ed97483c9ace0c19f0ded09;p=patchyircd.git net: recvProc clean up make it more in line with the original version of the code I wrote back in 2022 --- diff --git a/src/irc.cpp b/src/irc.cpp index aac2d9a..6519494 100644 --- a/src/irc.cpp +++ b/src/irc.cpp @@ -105,15 +105,15 @@ static int match_list(struct client_data *cl, stringset &list) return 1; return 0; } -int parsePacket(struct client_data *client) { +int irc_parse_line(struct client_data *client, char *p, char *end) { char *source = NULL; char *command = NULL; char *args[16] = {0}; int argc = 0; { - char *p = client->rbuf; { // remove \r - char *end = (char *)memchr(p, '\n', client->rlen); + if (!end) + end = strchr(p, '\n'); if (end > p && end[-1] == '\r') *--end = '\n'; if (memchr(p, '\0', end-p)) { @@ -175,7 +175,7 @@ int parsePacket(struct client_data *client) { } } fprintf(stderr, "\n"); - return processPacket(client, source, command, argc, args); + return irc_process_line(client, source, command, argc, args); } static void cont_webirc(struct client_data *client, int res) { if (!(client->umode & UMODE_SECURE) || res != 0) { @@ -233,7 +233,7 @@ static void cont_pass(struct client_data *client, int res) { newUser(client); } } -int processPacket(struct client_data *client, char *source, char *command, int argc, char *args[]) { +int irc_process_line(struct client_data *client, char *source, char *command, int argc, char *args[]) { (void)source; databuf.clear(); if(strcmp(command, "") == 0) { diff --git a/src/irc.h b/src/irc.h index 5fccdd6..235068e 100644 --- a/src/irc.h +++ b/src/irc.h @@ -11,8 +11,8 @@ #define is_registered(cl) ((cl)->regstate == REG_REGISTERED) void sendbuf_monitor(const char *nick, int cookie, int positive, int negative); const char *format_umodes(struct client_data *cl); -int parsePacket(struct client_data *client); -int processPacket(struct client_data *client, char *source, char *command, int argc, char *args[]); +int irc_parse_line(struct client_data *client, char *p, char *end); +int irc_process_line(struct client_data *client, char *source, char *command, int argc, char *args[]); void newUser(struct client_data *client); void sendLUSERS(struct client_data *client); void sendMOTD(struct client_data *client); diff --git a/src/main.cpp b/src/main.cpp index 692df41..d1394cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -298,46 +298,43 @@ int main(int argc, char *argv[]) if (!fake->hostname) abortf("strdup fail (hostname)\n"); strcpy_lit(fake->rbuf, "NICK :root\r\n"); - fake->rlen = strlen(fake->rbuf); - parsePacket(fake); + irc_parse_line(fake, fake->rbuf, 0); strcpy_lit(fake->rbuf, "USER root 0 * :Patchouli Knowledge\r\n"); - fake->rlen = strlen(fake->rbuf); - parsePacket(fake); + irc_parse_line(fake, fake->rbuf, 0); while (fgets(fake->rbuf, sizeof(fake->rbuf), f)) { + char *p = fake->rbuf; int len = strlen(fake->rbuf); if (!len || fake->rbuf[len-1] != '\n') break; unsigned long faketime; - if (sscanf(fake->rbuf, "$%lu", &faketime)) { + if (sscanf(p, "$%lu", &faketime)) { set_time((time_t)faketime); - char *p = strchr(fake->rbuf, ' '); + p = strchr(fake->rbuf, ' '); if (!p) continue; len -= ++p - fake->rbuf; memmove(fake->rbuf, p, len); } - if (fake->rbuf[0] == ':') { - char *sp = strchr(fake->rbuf, ' '); - char *bang = strchr(fake->rbuf, '!'); + if (*p == ':') { + char *sp = strchr(p, ' '); + char *bang = strchr(p, '!'); if (sp && bang && bang < sp) { - int nlen = bang - fake->rbuf - 1; - if (memcmp(&fake->rbuf[1], fake->nick, nlen) != 0) { + int nlen = bang - p - 1; + if (memcmp(&p[1], fake->nick, nlen) != 0) { char *nnick = (char *)malloc(nlen+1); if (!nnick) abortf("malloc fail (fake->nick)\n"); - memcpy(nnick, &fake->rbuf[1], nlen); + memcpy(nnick, &p[1], nlen); nnick[nlen] = '\0'; free(fake->nick); fake->nick = nnick; } } } - fake->rlen = len; - parsePacket(fake); + irc_parse_line(fake, p, 0); } strcpy_lit(fake->rbuf, "QUIT :bye\r\n"); - fake->rlen = strlen(fake->rbuf); - parsePacket(fake); + irc_parse_line(fake, fake->rbuf, 0); set_time(0); fclose(f); } @@ -380,11 +377,11 @@ int main(int argc, char *argv[]) break; case SOCKTYPE_CLIENT: { struct client_data *cl = (struct client_data *)ev.assoc; - /* NOTE: recvProc can kill the client, so writing should be done first. */ + /* NOTE: read_proc can kill the client, so writing should be done first. */ if ((cl->want_read_for_write && isr) || (cl->want_write_for_write && isw)) sendClient(cl, 0, 0); if (cl->want_write_for_read ? isw : isr) - recvProc(cl); + read_proc(cl); break; } case SOCKTYPE_DYING: { diff --git a/src/net.cpp b/src/net.cpp index a169f9c..8f17b1c 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -149,69 +149,64 @@ void killConnectionPart2(struct client_data *cl) delete cl; } -void recvProc(struct client_data *cl) { - ssize_t bytesRead; - char *x; - int packetReturn; +void read_proc(struct client_data *cl) +{ + constexpr int rcap = sizeof(cl->rbuf); cl->want_write_for_read = 0; for (;;) { - if(cl->rlen == sizeof(cl->rbuf)) { killConnection(cl, 0); return; } + if(cl->rlen == rcap) { + killConnection(cl, 0); + return; + } + ssize_t nread; #if HAVE_LIBTLS if (cl->cctx) { - bytesRead = tls_read(cl->cctx, cl->rbuf + cl->rlen, sizeof(cl->rbuf) - cl->rlen); - switch (bytesRead) { - // Disconnect - case 0: - killConnection(cl, 0); - return; - // Error - case -1: - fprintf(stderr, "tls_read: %s\n", tls_error(cl->cctx)); - killConnection(cl, 0); - return; - case TLS_WANT_POLLIN: - update_poll_reg(cl); - return; - case TLS_WANT_POLLOUT: - cl->want_write_for_read = 1; - update_poll_reg(cl); - return; + nread = tls_read(cl->cctx, cl->rbuf + cl->rlen, rcap - cl->rlen); + if (nread == TLS_WANT_POLLIN) { + update_poll_reg(cl); + return; + } else if (nread == TLS_WANT_POLLOUT) { + cl->want_write_for_read = 1; + update_poll_reg(cl); + return; + } else if (nread == -1) { + fprintf(stderr, "tls_read: %s\n", tls_error(cl->cctx)); + killConnection(cl, 0); + return; } } else #endif { - bytesRead = recv(cl->fd, cl->rbuf + cl->rlen,sizeof(cl->rbuf) - cl->rlen, 0); - switch(bytesRead){ - // Disconnect - case 0: + nread = recv(cl->fd, cl->rbuf + cl->rlen, rcap - cl->rlen, 0); + if (nread == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + update_poll_reg(cl); + } else { + perror("recv"); killConnection(cl, 0); - return; - // Error - case -1: - if (errno != EAGAIN && errno != EWOULDBLOCK) { - perror("recv"); - killConnection(cl, 0); - } else { - update_poll_reg(cl); - } - return; + } + return; } } - cl->rlen += bytesRead; - while(1){ - x = (char *)memchr(cl->rbuf, '\n', cl->rlen); - if(!x) break; - packetReturn = parsePacket(cl); - // Client QUIT - if (packetReturn == 1) + if (nread == 0) { + killConnection(cl, 0); + return; + } + cl->rlen += nread; + for (;;) { + char *p = (char *)memchr(cl->rbuf, '\n', cl->rlen); + if (!p) + break; + if (irc_parse_line(cl, cl->rbuf, p) == 1) return; + p++; + memmove(cl->rbuf, p, cl->rbuf + cl->rlen - p); + cl->rlen -= p - cl->rbuf; if (cl->write_error) { update_poll_reg(cl); return; } - memmove(cl->rbuf, x+1, cl->rbuf + cl->rlen-(x+1)); - cl->rlen -= x+1 - cl->rbuf; } } } diff --git a/src/net.h b/src/net.h index a2c5adc..a35e64b 100644 --- a/src/net.h +++ b/src/net.h @@ -11,7 +11,7 @@ void update_poll_reg(struct client_data *cl); void log_client(struct client_data *cl, const char *format, ...); void killConnection(struct client_data *client, int byChoice); void killConnectionPart2(struct client_data *cl); -void recvProc(struct client_data *cl); +void read_proc(struct client_data *cl); void sendClient(struct client_data *cl, const char *buf, size_t len); #endif