nbeng

a non-blocking client/server engine
git clone git://git.2f30.org/nbeng.git
Log | Files | Refs | README

commit 63682f042738092c324ed23ec553598af5cbcfcb
parent ba767a66b0881490fa34cb6fd810260e3d13d9df
Author: dsp <dsp@2f30.org>
Date:   Tue Jul  3 03:43:08 +0300

commited 2 more patches from lostd@ which fix select() logic and better abstract the code.

Diffstat:
nbeng.c | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 97 insertions(+), 42 deletions(-)
diff --git a/nbeng.c b/nbeng.c @@ -34,6 +34,7 @@ typedef struct concontxt_t { #define SSLCON 3 unsigned int contype; /* connection type */ int confd; /* net connection fd */ + int clifd; int clifds[FD_SETSIZE]; /* for tcp connected clients */ fd_set lset; /* the set that we select() on */ struct addrinfo *clinfo; /* info on where we connect */ @@ -89,11 +90,7 @@ static void prepare_socket(concontxt *con, char *host, char *port) { struct addrinfo cli_hints, *cli_servinfo, srv_hints, *srv_servinfo, *p0; - int rv, cli_sockfd, optval = 1, i; - - /* all client fds are available */ - for (i = 0; i < FD_SETSIZE; i++) - con->clifds[i] = -1; + int rv, cli_sockfd, optval = 1; if ((con == NULL) || (host == NULL) || (port == NULL)) errx(1, "prepare_socket was passed a null arg"); @@ -139,8 +136,8 @@ prepare_socket(concontxt *con, char *host, char *port) if (!p0) errx(1, "failed to bind socket"); /* if it's a tcp connection we have to listen() */ - if (con->contype != UDPCON) - listen(cli_sockfd, 5); +// if (con->contype != UDPCON) +// listen(cli_sockfd, 5); /* all was ok, so we register the socket to the context */ con->confd = cli_sockfd; con->clinfo = cli_servinfo; @@ -190,35 +187,26 @@ freex: static void writesock(concontxt *con) { - ssize_t sent; - int newfd; - int i; + ssize_t n; /* nothing to do */ if (con->buf == NULL) return; if (con->contype == UDPCON) { - sent = sendto(con->confd, con->buf, con->buflen, 0, + n = sendto(con->confd, con->buf, con->buflen, 0, con->clinfo->ai_addr, con->clinfo->ai_addrlen); - if (sent < 0) + if (n < 0) warn("sendto"); } else { - newfd = connect(con->confd, - con->clinfo->ai_addr, - con->clinfo->ai_addrlen); - printf("newfd=%d\n", newfd); - if (newfd < 0) { - warn("connect"); + n = write(con->clifd, con->buf, con->buflen); + if (n < 0) { + warn("write"); + close(con->clifd); + con->clifd = -1; goto freex; } - for (i = 0; i < FD_SETSIZE; i++) { - if (con->clifds[i] == -1) { - con->clifds[i] = newfd; - break; - } - } } freex: @@ -246,9 +234,26 @@ readsock(concontxt *con) if (con->contype == UDPCON) { n = recvfrom(con->confd, buf, sizeof (buf), MSG_DONTWAIT, (struct sockaddr *)&their_addr, &addr_len); + if (n < 0) { + warn("recvfrom"); + goto freex; + } + + /* resolv */ + r = getnameinfo((struct sockaddr *)&their_addr, addr_len, + host, sizeof (host), NULL, 0, 0); + if (r < 0) { + warn("getnameinfo"); + snprintf(host, sizeof (host), "unknown"); + } + printf("host=%s\n", host); } else { - /* code for tcp */ - n = 0; + n = read(con->clifd, buf, sizeof (buf)); + if (n == 0) { + close(con->clifd); + con->clifd = -1; + goto freex; + } } buf[n] = '\0'; @@ -259,16 +264,7 @@ readsock(concontxt *con) } memcpy(con->buf, buf, n); con->buflen = n; - - if (n > 0) { - r = getnameinfo((struct sockaddr *)&their_addr, addr_len, - host, sizeof (host), NULL, 0, 0); - if (r < 0) { - warn("getnameinfo"); - snprintf(host, sizeof (host), "unknown"); - } - } - printf("host=%s n=%zd buf=%s", host, n, buf); + printf("n=%zd buf=%s", n, buf); return; freex: @@ -294,10 +290,55 @@ writestdout(concontxt *con) return; } +static void +myaccept(concontxt *con) +{ + int r; + char host[NI_MAXHOST]; + int newfd; + struct sockaddr_storage sa; + socklen_t salen = sizeof (sa); + + newfd = accept(con->confd, (struct sockaddr *)&sa, &salen); + printf("newfd=%d\n", newfd); + if (newfd < 0) { + warn("accept"); + return; + } + con->clifd = newfd; + + /* resolv */ + r = getnameinfo((struct sockaddr *)&sa, salen, + host, sizeof (host), NULL, 0, 0); + if (r < 0) { + warn("getnameinfo"); + snprintf(host, sizeof (host), "unknown"); + } + printf("host=%s\n", host); + return; +} + +static void +myconnect(concontxt *con) +{ + int r; + + r = connect(con->confd, + con->clinfo->ai_addr, + con->clinfo->ai_addrlen); + printf("newfd=%d\n", con->confd); + if (r < 0) { + warn("connect"); + return; + } + con->clifd = con->confd; + return; +} + int main(int argc, char *argv[]) { - int c, i; + int c; int highsock, readsocks; struct timeval timeout; char *host, *port; @@ -330,6 +371,7 @@ main(int argc, char *argv[]) con->wfd = fileno(stdin); con->lfd = fileno(stdout); con->contype = (tflag || sflag) ? TCPCON : UDPCON; + con->clifd = -1; prepare_socket(con, host, port); @@ -341,9 +383,9 @@ main(int argc, char *argv[]) FD_SET(con->wfd, &(con->lset)); FD_SET(con->confd, &(con->lset)); highsock = con->confd; - /* add all connected clients */ - for (i = 0; i < FD_SETSIZE && con->clifds[i] != -1; i++) { - FD_SET(con->clifds[i], &(con->lset)); + if (con->clifd != -1) { + FD_SET(con->clifd, &(con->lset)); + highsock = con->clifd; } if (qflag) goto freex; @@ -359,10 +401,23 @@ main(int argc, char *argv[]) fflush(stdout); } else { if (FD_ISSET(con->wfd, &(con->lset))) { - readstdin(con); - writesock(con); + if (con->clifd == -1 + && con->contype != UDPCON) + myconnect(con); + readstdin(con); + writesock(con); } if (FD_ISSET(con->confd, &(con->lset))) { + if (con->contype == UDPCON) { + readsock(con); + writestdout(con); + } else { + if (con->clifd == -1) + myaccept(con); + } + } + if (con->clifd != -1 && + FD_ISSET(con->clifd, &(con->lset))) { readsock(con); writestdout(con); }