nbeng

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

commit 82e1b2743bbd196111d0a5c93741f0feed2e02e0
Author: dsp <dsp@2f30.org>
Date:   Thu, 14 Jun 2012 14:23:39 +0300

initial release, client logic only

Diffstat:
AMakefile | 24++++++++++++++++++++++++
AREADME | 8++++++++
Anbeng.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 185 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,24 @@ +BIN = nbeng +VER = 0.1-alpha +SRC = nbeng.c +OBJ = ${SRC:.c=.o} + +CC = gcc + +INCS = -I/usr/local/include +LIBS = -L/usr/local/lib + +CFLAGS += -Wall -Wextra -Wunused -DVERSION=\"${VER}\" ${INCS} +#add assl +#LDFLAGS += -lassl ${LIBS} + +$(BIN): ${OBJ} + ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJ} + +%.o: %.c + ${CC} ${CFLAGS} -c -o $@ $< + +clean: + rm -rf ${BIN} ${OBJ} + +all: nbeng diff --git a/README b/README @@ -0,0 +1,8 @@ +NonBlockingENGine by <dsp@2f30.org> + +A nonblocking client/server engine for future use on sscall. +(https://github.com/quantumdream/sscall.git) +Will support SSL connections via ASSL. +to test get a netcat proccess listening for udp on a port: +nc -ul 127.0.0.1 8888 +./nbeng 127.0.0.1 8888 1234 diff --git a/nbeng.c b/nbeng.c @@ -0,0 +1,153 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <ctype.h> +#include <sys/time.h> +#include <fcntl.h> +#include <err.h> + +/*SSL flag*/ +int fssl=0; + +/*connection context */ +typedef struct concontxt_t { + int clifd; /*client fd*/ + int srvfd; /*server fd*/ + struct addrinfo *clinfo; + struct addrinfo *srvinfo; +} concontxt; + +static void +usage(const char *s) +{ + fprintf(stderr, + "usage: %s [OPTIONS] <remote-addr> <remote-port> <local-port>\n", s); + fprintf(stderr, " -s\tSSL on\n"); + fprintf(stderr, " -h\tThis help screen\n"); +} + +/*connect to in port port and store the fds in the context*/ +static void +connectit(concontxt *c,char *to,char *port){ + struct addrinfo cli_hints, *cli_servinfo, *p0; + int rv,cli_sockfd; + if( (c==NULL) || (to == NULL) || (port == NULL)) + errx(1,"conectit was passed a null arg"); + memset(&cli_hints, 0, sizeof(cli_hints)); + cli_hints.ai_family = AF_INET; + cli_hints.ai_socktype = SOCK_DGRAM; + + rv = getaddrinfo(to, port, &cli_hints, &cli_servinfo); + if (rv) + errx(1, "getaddrinfo: %s", gai_strerror(rv)); + + for (p0 = cli_servinfo; p0; p0 = p0->ai_next) { + cli_sockfd = socket(p0->ai_family, p0->ai_socktype, + p0->ai_protocol); + if (cli_sockfd < 0) + continue; + break; + } + if (!p0) + errx(1, "failed to bind socket"); + /*all was ok , so we register the socket to the context*/ + c->clifd=cli_sockfd; + c->clinfo=cli_servinfo; +} + +int +main(int argc,char *argv[]) +{ + /*our input is the stdin for now, we record lines and send them*/ + int recfd=STDIN_FILENO; + char *prog = *argv; + int c; + fd_set rsocks; + int highsock,readsocks; + struct timeval timeout; + char *inbuf=NULL,*linbuf=NULL; + ssize_t inbufln; + concontxt *con = (concontxt*) malloc(sizeof(concontxt)); + while ((c = getopt(argc, argv, "hs")) != -1) { + switch (c) { + case 'h': + usage(prog); + goto freex; + break; + case 's': + fssl=1; + break; + case '?': + default: + goto freex; + } + } + argc -= optind; + argv += optind; + + if (argc != 3) { + usage(prog); + goto freex; + } + /*connect to the host*/ + connectit(con,argv[0],argv[1]); + /*XXX: this should change when we add the srv fd*/ + highsock = recfd; + /*these are the sockets for reading (stdin + server fd)*/ + while (1) { + FD_ZERO(&rsocks); + FD_SET(recfd,&rsocks); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + readsocks = select(highsock+1, &rsocks, (fd_set *) 0, + (fd_set *) 0, &timeout); + if (readsocks < 0) { + warnx("select error"); + goto freex; + } + if (readsocks == 0) { + /*show that we are alive*/ + printf("."); + fflush(stdout); + } else { + if (FD_ISSET(recfd,&rsocks)){ + /*deal with input data*/ + inbuf = fgetln(stdin,&inbufln); + if (inbuf[inbufln - 1] == '\n') + inbuf[inbufln - 1] = '\0'; + else { + /* EOF without EOL, copy and add the NUL */ + if ((linbuf = malloc(inbufln + 1)) == NULL){ + warnx("linbuf alloc failed"); + goto freex; + } + memcpy(linbuf, inbuf, inbufln); + linbuf[inbufln] = '\0'; + inbuf = linbuf; + } + if ((strncmp(inbuf,"Q",2)==0)) + goto freex; + printf("got msg: %s , sending it \n",inbuf); + sendto(con->clifd,inbuf,inbufln,0,con->clinfo->ai_addr,con->clinfo->ai_addrlen); + fflush(stdout); + /*free the buf*/ + if(linbuf != NULL) + free(linbuf); + } + } + } + +freex: if (con != NULL){ + close(con->clifd); + free(con); + } + if (inbuf != NULL) + free(inbuf); + return 0; +}