int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; int result; fd_set readfds, testfds; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = INADDR_ANY; server_address.sin_port = htons(9734); server_len = sizeof(server_address); bind(server_sockfd, (struct sockaddr *)&server_address, server_len); listen(server_sockfd, 5); FD_ZERO(&readfds); FD_SET(server_sockfd, &readfds); while (1) { char ch; int fd; int nread; testfds = readfds; printf("server waiting\n"); result = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); if (result < 1) { perror("server5"); exit(1); } for (fd = 0; fd < FD_SETSIZE; fd++) { if (FD_ISSET(fd, &testfds)) { if (fd == server_sockfd) { client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); FD_SET(client_sockfd, &readfds); printf("add client on fd %d\n", client_sockfd); } else { ioctl(fd, FIONREAD, &nread); if (nread == 0) { close(fd); FD_CLR(fd, &readfds); printf("removing client on fd %d\n", fd); } else { read(fd, &ch, 1); sleep(5); printf("serving client on fd %d\n", fd); ch++; write(fd, &ch, 1); } } } } } }
extract::process::output const extract::process::call( argument_list const &_args) { FCPPT_ASSERT( !_args.empty()); std::size_t const reading_end = static_cast<std::size_t>( 0), writing_end = static_cast<std::size_t>( 1); int out_pipe[2]; int err_pipe[2]; if (pipe(out_pipe) == -1 || pipe(err_pipe) == -1) throw fcppt::exception( FCPPT_TEXT("one of the pipes failed")); pid_t const pid = fork(); if (pid == 0) { close( out_pipe[reading_end]); close( err_pipe[reading_end]); dup2( out_pipe[writing_end], STDOUT_FILENO); dup2( err_pipe[writing_end], STDERR_FILENO); close( out_pipe[writing_end]); close( err_pipe[writing_end]); exec( _args); } close( out_pipe[writing_end]); close( err_pipe[writing_end]); fd_set master_fds; FD_ZERO( &master_fds); FD_SET( out_pipe[reading_end], &master_fds); FD_SET( err_pipe[reading_end], &master_fds); output out; int eof_count = 0; while (eof_count < 2) { fd_set read_fds = master_fds; int maxfd = std::max( out_pipe[reading_end], err_pipe[reading_end]), select_return = select( maxfd+1, &read_fds, 0, 0, 0); if (select_return == -1) throw fcppt::exception( FCPPT_TEXT("select failed")); int const fds[2] = { out_pipe[reading_end], err_pipe[reading_end] }; fcppt::string *outs[2] = { &out.out, &out.err }; for (int i = 0; i < 2; ++i) { if (!FD_ISSET(fds[i],&read_fds)) continue; ssize_t const buffer_size = static_cast<ssize_t>( 1024); char char_buffer[buffer_size]; ssize_t const b = ::read( fds[i], char_buffer, static_cast<std::size_t>( buffer_size-1)); if (b == static_cast<ssize_t>(0)) { // fcppt::io::cerr << "recieved eof on fd " << fds[i] << "\n"; eof_count++; FD_CLR( fds[i], &master_fds); continue; } if (b == static_cast<ssize_t>(-1)) throw fcppt::exception( FCPPT_TEXT("read failed")); // fcppt::io::cerr << "received the following crap: " << fcppt::string(char_buffer,char_buffer+b) << "\n"; outs[i]->insert( outs[i]->end(), char_buffer, char_buffer + b); } } waitpid( pid, (&out.exit_code), 0); return out; }
void relay_tcp(SOCKS_STATE *state) { fd_set rfds, xfds; int nfds, sfd; struct timeval tv; struct timezone tz; ssize_t wc; rlyinfo ri; int done; u_long max_count = idle_timeout; u_long timeout_count; LOGINFO li; memset(&ri, 0, sizeof(ri)); memset(&li, 0, sizeof(li)); ri.ss = (struct sockaddr *)NULL; ri.len = 0; ri.nr = BUFSIZE; nfds = MAX(state->r, state->s); setsignal(SIGALRM, timeout); gettimeofday(&li.start, &tz); li.bc = li.upl = li.dnl = 0; ri.flags = 0; timeout_count = 0; for (;;) { FD_ZERO(&rfds); FD_SET(state->s, &rfds); FD_SET(state->r, &rfds); if (ri.flags == 0) { FD_ZERO(&xfds); FD_SET(state->s, &xfds); FD_SET(state->r, &xfds); } done = 0; /* idle timeout related setting. */ tv.tv_sec = 60; tv.tv_usec = 0; /* unit = 1 minute. */ tz.tz_minuteswest = 0; tz.tz_dsttime = 0; sfd = select(nfds+1, &rfds, 0, &xfds, &tv); if (sfd > 0) { if (FD_ISSET(state->r, &rfds)) { ri.from = state->r; ri.to = state->s; ri.flags = 0; if ((wc = forward(&ri)) <= 0) done++; else li.bc += wc; li.dnl += wc; FD_CLR(state->r, &rfds); } if (FD_ISSET(state->r, &xfds)) { ri.from = state->r; ri.to = state->s; ri.flags = MSG_OOB; if ((wc = forward(&ri)) <= 0) done++; else li.bc += wc; li.dnl += wc; FD_CLR(state->r, &xfds); } if (FD_ISSET(state->s, &rfds)) { ri.from = state->s; ri.to = state->r; ri.flags = 0; if ((wc = forward(&ri)) <= 0) done++; else li.bc += wc; li.upl += wc; FD_CLR(state->s, &rfds); } if (FD_ISSET(state->s, &xfds)) { ri.from = state->s; ri.to = state->r; ri.flags = MSG_OOB; if ((wc = forward(&ri)) <= 0) done++; else li.bc += wc; li.upl += wc; FD_CLR(state->s, &xfds); } if (done > 0) break; } else if (sfd < 0) { if (errno != EINTR) break; } else { /* sfd == 0 */ if (max_count != 0) { timeout_count++; if (timeout_count > max_count) break; } } } gettimeofday(&li.end, &tz); log_transfer(state->si, &li); close(state->r); close(state->s); }
/** * new connecion comes, copy file descroptor of new connecton to child * process , parent process select * @return 0 */ int main(int argc, char **argv) { int res; res = register_sig_handler(); if (res < 0) err_sys("register_sig_handler is err"); my_getopt(argc, argv); int pipefd[2]; int socket_fd; res = srv_socket_init(&socket_fd, 50, PORT); if (res < 0) err_sys("srv_socket_init err"); fd_set myset; FD_ZERO(&myset); FD_SET(socket_fd, &myset); int max = socket_fd; arraychild = (child_t *) malloc(sizeof(child_t) * childnum); memset(arraychild, 0, sizeof(child_t) * childnum); for (int i = 0 ; i < childnum; i++) { res = socketpair(AF_LOCAL, SOCK_STREAM, 0, pipefd); if (res < 0) err_sys("socketpair is err"); arraychild[i].child_pipefd = pipefd[0]; FD_SET(pipefd[0], &myset); if (pipefd[0] > max) max = pipefd[0]; int pid = fork(); if (pid < 0) err_sys("fork err"); if (pid == 0) { srv_socket_destory(&socket_fd); int connfd; int childpid = getpid(); while(1) { char c; res = read_fd(pipefd[1], &c, 1, &connfd); if (res < 0) err_sys("read_fd err"); fprintf(stdout, "pid is %d, accept success.\n",childpid); child_process(connfd); write(pipefd[1], "", 1); srv_socket_close(&connfd); } //exit(0); } else { arraychild[i].child_pid = pid; } } struct sigaction myact; myact.sa_handler = sig_int_handler; if (sigaction(SIGINT, &myact, NULL) < 0) err_sys("sigaction err"); int navail = childnum; fd_set rset ; int newfd; int i = 0; while(1) { rset = myset; if (navail <=0 ) FD_CLR(socket_fd, &rset); select(max + 1, &rset, NULL, NULL, NULL); if (FD_ISSET(socket_fd, &rset)) { newfd = accept(socket_fd, NULL, NULL); for (i = 0; i < childnum; i++) { if (arraychild[i].child_status == 0) break; } res = write_fd(arraychild[i].child_pipefd, "", 1, newfd); if (res < 0) { continue; } srv_socket_close(&newfd); arraychild[i].child_status = 1; arraychild[i].child_count++; navail--; } for (int i = 0; i < childnum; i++) { char c; if (FD_ISSET(arraychild[i].child_pipefd, &rset)) { read(arraychild[i].child_pipefd, &c, 1); arraychild[i].child_status = 0; navail++; } } } return 0; }
int main() { int fd, novofd,nbytes,j,fdmax; struct sockaddr_in addr, client_addr; int client_addr_size; char buffer[BUF_SIZE]; int clientes_fd[MAX];// array com o fds dos clientes fd_set master; // descritor de arquivo mestre fd_set ler_fds; // descritor de arquivo para temporario FD_ZERO(&master); //limpa os conjuntos mestre e temporário FD_ZERO(&ler_fds); int yes=1; bzero((void *) &addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(SERVER_PORT); if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) erro("na funcao socket"); if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (int)) == -1) { perror ("setsockopt"); exit (1); } if ( bind(fd,(struct sockaddr*)&addr,sizeof(addr)) < 0) erro("na funcao bind"); if( listen(fd, 100) < 0) erro("na funcao listen"); //adiciona o socket em escura ao conjunto master FD_SET(fd, &master); clientes_fd[0]=fd; fdmax=fd; while(1){ ler_fds = master; // copia os master para o temporario if (select (fdmax+1, &ler_fds, NULL, NULL, NULL)== -1) { perror ("select"); exit(1); } int i;// percorre as conexões existentes em busca de dados for ( i = 0; i <=fdmax; i++) { if ( FD_ISSET ( i, &ler_fds)) { if ( i == clientes_fd[0]) { //trata novas conexões client_addr_size = sizeof(client_addr); if (( novofd = accept(fd,(struct sockaddr *)&client_addr, &client_addr_size)) == -1) { perror ("accept"); } else { FD_SET ( novofd , &master);//adiciona ao mestre char print[150]="->"; char t[5]; strcat(print,"servidor : nova conexão de "); strcat(print, inet_ntoa(client_addr.sin_addr)); strcat(print," no socket "); sprintf(t, "%d", novofd); strcat(print, t); strcat(print, "\n"); for (j = 0; j<MAX; j++) { //envia a todos os clientes if (FD_ISSET (j, &master)) { // exceto a nós e ao socket em escuta if (j != fd &&j != novofd) { if (write(j,print,strlen(print)) == -1) { perror ("write"); }}}} print[0]='\0'; if(fdmax<novofd){ fdmax=novofd; novofd=0; } clientes_fd[coloca_array(clientes_fd)]=novofd; }} else { // cuida dos dados do cliente if ( (nbytes=(read (i, buffer, BUF_SIZE-1)))>= 0) { // recebeu erro ou a conexão foifechada pelo cliente if (nbytes == 0) { char printR[150]="->"; char p[5]; strcat(printR," servidor : o Cliente foi desligado "); strcat(printR, inet_ntoa(client_addr.sin_addr)); strcat(printR," no socket "); sprintf(p, "%d", i); strcat(printR, p); strcat(printR, "\n"); for (j = 0; j<MAX; j++) { //envia a todos os clientes if (FD_ISSET (j, &master)) { // menos aos nós e ao socket em escuta if (j != fd &&j != novofd) { if (write(j,printR,strlen(printR)) == -1) { perror ("write"); }}}} printR[0]='\0'; FD_CLR( i , &master); // clear do conjunto mestre search(clientes_fd, i); } else if(nbytes==-1) { perror ("read"); } } // temos alguns dados do cliente for (j = 0; j<MAX; j++) { //envia a todos os clientes if (FD_ISSET (j, &master)) { // exceto a nós e ao socket em escuta if (j != fd &&j!=i ) { if (write(j,buffer,nbytes) == -1) { perror ("write"); } } } } } } } } return 0; }
/* handle irc server connectipn */ void irc_perform(int changesec) { channel_t *ch; unsigned int ss; unsigned int i; unsigned int j; int length; int timeout; updatecontext(); for (ss=0; ss<gdata.networks_online; ++ss) { gnetwork = &(gdata.networks[ss]); if (gdata.needsswitch) { switchserver(-1); continue; } /*----- see if gdata.ircserver is sending anything to us ----- */ if (gnetwork->serverstatus == SERVERSTATUS_CONNECTED) { if (FD_ISSET(gnetwork->ircserver, &gdata.readset)) { char tempbuffa[INPUT_BUFFER_LENGTH]; gnetwork->lastservercontact = gdata.curtime; gnetwork->servertime = 0; memset(&tempbuffa, 0, INPUT_BUFFER_LENGTH); length = readserver_ssl(&tempbuffa, INPUT_BUFFER_LENGTH); if (length < 1) { if (errno != EAGAIN) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Closing Server Connection on %s: %s", gnetwork->name, (length<0) ? strerror(errno) : "Closed"); if (gdata.exiting) { gnetwork->recentsent = 0; } close_server(); mydelete(gnetwork->curserveractualname); } continue; } j = strlen(gnetwork->server_input_line); for (i=0; i<(unsigned int)length; ++i) { if ((tempbuffa[i] == '\n') || (j == (INPUT_BUFFER_LENGTH-1))) { if (j && (gnetwork->server_input_line[j-1] == 0x0D)) { --j; } gnetwork->server_input_line[j] = '\0'; ir_parseline(gnetwork->server_input_line); j = 0; } else { gnetwork->server_input_line[j] = tempbuffa[i]; ++j; } } gnetwork->server_input_line[j] = '\0'; } continue; } if (gnetwork->serverstatus == SERVERSTATUS_SSL_HANDSHAKE) { if ((FD_ISSET(gnetwork->ircserver, &gdata.writeset)) || (FD_ISSET(gnetwork->ircserver, &gdata.readset))) { handshake_ssl(); } if (changesec) irc_server_timeout(); continue; } if (gnetwork->serverstatus == SERVERSTATUS_TRYING) { if (FD_ISSET(gnetwork->ircserver, &gdata.writeset)) { int callval_i; int connect_error; SIGNEDSOCK int connect_error_len = sizeof(connect_error); SIGNEDSOCK int addrlen; callval_i = getsockopt(gnetwork->ircserver, SOL_SOCKET, SO_ERROR, &connect_error, &connect_error_len); if (callval_i < 0) { outerror(OUTERROR_TYPE_WARN, "Couldn't determine connection status: %s on %s", strerror(errno), gnetwork->name); close_server(); continue; } if (connect_error) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Server Connection Failed: %s on %s", strerror(connect_error), gnetwork->name); close_server(); continue; } ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Server Connection to %s Established, Logging In", gnetwork->name); gnetwork->serverstatus = SERVERSTATUS_CONNECTED; gnetwork->connecttime = gdata.curtime; gnetwork->botstatus = BOTSTATUS_LOGIN; ch = irlist_get_head(&(gnetwork->channels)); if (ch == NULL) { gnetwork->botstatus = BOTSTATUS_JOINED; start_sends(); } FD_CLR(gnetwork->ircserver, &gdata.writeset); addrlen = sizeof(gnetwork->myip); bzero((char *) &(gnetwork->myip), sizeof(gnetwork->myip)); if (getsockname(gnetwork->ircserver, &(gnetwork->myip.sa), &addrlen) >= 0) { if (gdata.debug > 0) { char *msg; msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(gnetwork->myip.sa)); ioutput(OUT_S, COLOR_YELLOW, "using %s", msg); mydelete(msg); } if (!gnetwork->usenatip) { gnetwork->ourip = ntohl(gnetwork->myip.sin.sin_addr.s_addr); if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "ourip = " IPV4_PRINT_FMT, IPV4_PRINT_DATA(gnetwork->ourip)); } } } else { outerror(OUTERROR_TYPE_WARN, "couldn't get ourip on %s", gnetwork->name); } handshake_ssl(); } if (changesec) irc_server_timeout(); continue; } if (gnetwork->serverstatus == SERVERSTATUS_RESOLVING) { if (FD_ISSET(gnetwork->serv_resolv.sp_fd[0], &gdata.readset)) { res_addrinfo_t remote; length = read(gnetwork->serv_resolv.sp_fd[0], &remote, sizeof(res_addrinfo_t)); kill(gnetwork->serv_resolv.child_pid, SIGKILL); FD_CLR(gnetwork->serv_resolv.sp_fd[0], &gdata.readset); if (length != sizeof(res_addrinfo_t)) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Error resolving server %s on %s", gnetwork->curserver.hostname, gnetwork->name); gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT; } else { /* continue with connect */ if (connectirc2(&remote)) { /* failed */ gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT; } } } if (changesec) { timeout = irc_server_is_timeout(); if (timeout > 0) { kill(gnetwork->serv_resolv.child_pid, SIGKILL); ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Server Resolve Timed Out (%u seconds) on %s", timeout, gnetwork->name); gnetwork->serverstatus = SERVERSTATUS_NEED_TO_CONNECT; } } continue; } if (gnetwork->offline) continue; if (gnetwork->serverstatus == SERVERSTATUS_NEED_TO_CONNECT) { if (changesec) { timeout = irc_server_is_timeout(); if (timeout > 0) { if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "Reconnecting to server (%u seconds) on %s", timeout, gnetwork->name); } switchserver(-1); } } continue; } } /* networks */ gnetwork = NULL; /* reset after done on all networks */ if (gdata.needsswitch) gdata.needsswitch = 0; }
int main(int argc,char *argv[]){ int i,fd,nmaxconn,nfiles,maxfd,nconn,flags; char buf[MAXLINE]; fd_set rs,ws; if(argc < 4) err_quit("usage : web <#conn> hostname homepage file1 ..."); nmaxconn = atoi(argv[1]); nfiles = min(argc-4,MAXFILES); for(i=0;i<nfiles;i++){ file[i].f_name = argv[4+i]; file[i].f_host = argv[2]; file[i].flags = 0; } home_page(argv[2],argv[3]); FD_ZERO(&rs); FD_ZERO(&ws); maxfd = -1; nconn = 0; nleftconn = nlefttoread = nfiles; while(nlefttoread > 0){ while(nconn < nmaxconn && nleftconn > 0){ for(i=0;i<nfiles;i++) if(file[i].flags != 0) break; if(i == nfiles) err_quit("nleftconn = %d but nothing found\n",nleftconn); start_connect(&file[i]); nconn++; nleftconn--; } rs = rset; ws = wset; Select(maxfd+1,&rset,&wset,NULL,NULL); for(i=0;i<nfiles;i++){ flags = file[i].flags; if(flags == 0 || flags == F_DONE) continue; fd = file[i].f_fd; if(flags & F_CONNECTING && (FD_ISSET(fd,&rset) || FD_ISSET(fd,&wset))){ n=sizeof(error); if(getsockopt(fd,SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0) err_ret("nonblocking connect failed for %s\n",file[i].f_name); printf("connection established for %s\n",file[i].f_name); FD_CLR(fd,&wset); write_get_cmd(&file[i]); }else if(flags & F_READING && FD_ISSET(fd,&rset)){ if((n = nread(fd,buf,sizeof(buf))) == 0){ printf("end-of-file on %s\n",file[i].f_name); Close(fd); file[i].flags = F_DONE; FD_CLR(fd,&rset); nconn--; nlefconn--; nlefttoread--; }else { printf("read %d bytes from %s\n",n,file[i].f_name); } } } } exit(0); }
/*** Call Manager *************************************************************/ int callmgr_main(int argc, char **argv, char **envp) { struct in_addr inetaddr; int inet_sock, unix_sock; fd_set call_set; PPTP_CONN * conn; VECTOR * call_list; int max_fd = 0; volatile int first = 1; int retval; int i; char * volatile phonenr; /* Step 0: Check arguments */ if (argc < 2) fatal("Usage: %s ip.add.ress.here [--phone <phone number>]", argv[0]); phonenr = argc == 3 ? argv[2] : NULL; if (inet_aton(argv[1], &inetaddr) == 0) fatal("Invalid IP address: %s", argv[1]); routing_init(inet_ntoa(inetaddr)); routing_start(); /* Step 1: Open sockets. */ if ((inet_sock = open_inetsock(inetaddr)) < 0) fatal("Could not open control connection to %s", argv[1]); if ((unix_sock = open_unixsock(inetaddr)) < 0) fatal("Could not open unix socket for %s", argv[1]); /* Step 1b: FORK and return status to calling process. */ switch (fork()) { case 0: /* child. stick around. */ break; case -1: /* failure. Fatal. */ fatal("Could not fork."); default: /* Parent. Return status to caller. */ exit(0); } /* re-open stderr as /dev/null to release it */ file2fd("/dev/null", "wb", STDERR_FILENO); /* Step 1c: Clean up unix socket on TERM */ if (sigsetjmp(callmgr_env, 1) != 0) goto cleanup; signal(SIGINT, callmgr_sighandler); signal(SIGTERM, callmgr_sighandler); signal(SIGPIPE, callmgr_do_nothing); signal(SIGUSR1, callmgr_do_nothing); /* signal state change wake up accept */ /* Step 2: Open control connection and register callback */ if ((conn = pptp_conn_open(inet_sock, 1, NULL/* callback */)) == NULL) { close(unix_sock); close(inet_sock); fatal("Could not open connection."); } FD_ZERO(&call_set); call_list = vector_create(); { struct local_conninfo *conninfo = malloc(sizeof(*conninfo)); if (conninfo == NULL) { close(unix_sock); close(inet_sock); fatal("No memory."); } conninfo->call_list = call_list; conninfo->call_set = &call_set; pptp_conn_closure_put(conn, conninfo); } if (sigsetjmp(callmgr_env, 1) != 0) goto shutdown; /* Step 3: Get FD_SETs */ max_fd = unix_sock; do { int rc; fd_set read_set = call_set, write_set; FD_ZERO (&write_set); if (pptp_conn_established(conn)) { FD_SET (unix_sock, &read_set); if (unix_sock > max_fd) max_fd = unix_sock; } pptp_fd_set(conn, &read_set, &write_set, &max_fd); for (; max_fd > 0 ; max_fd--) { if (FD_ISSET (max_fd, &read_set) || FD_ISSET (max_fd, &write_set)) break; } /* Step 4: Wait on INET or UNIX event */ if ((rc = select(max_fd + 1, &read_set, &write_set, NULL, NULL)) <0) { if (errno == EBADF) break; /* a signal or somesuch. */ continue; } /* Step 5a: Handle INET events */ rc = pptp_dispatch(conn, &read_set, &write_set); if (rc < 0) break; /* Step 5b: Handle new connection to UNIX socket */ if (FD_ISSET(unix_sock, &read_set)) { /* New call! */ struct sockaddr_un from; socklen_t len = sizeof(from); PPTP_CALL * call; struct local_callinfo *lci; int s; /* Accept the socket */ FD_CLR (unix_sock, &read_set); if ((s = accept(unix_sock, (struct sockaddr *) &from, &len)) < 0) { warn("Socket not accepted: %s", strerror(errno)); goto skip_accept; } /* Allocate memory for local call information structure. */ if ((lci = malloc(sizeof(*lci))) == NULL) { warn("Out of memory."); close(s); goto skip_accept; } lci->unix_sock = s; /* Give the initiator time to write the PIDs while we open * the call */ call = pptp_call_open(conn, call_callback, phonenr); /* Read and store the associated pids */ read(s, &lci->pid[0], sizeof(lci->pid[0])); read(s, &lci->pid[1], sizeof(lci->pid[1])); /* associate the local information with the call */ pptp_call_closure_put(conn, call, (void *) lci); /* The rest is done on callback. */ /* Keep alive; wait for close */ retval = vector_insert(call_list, s, call); assert(retval); if (s > max_fd) max_fd = s; FD_SET(s, &call_set); first = 0; } skip_accept: /* Step 5c: Handle socket close */ for (i = 0; i < max_fd + 1; i++) if (FD_ISSET(i, &read_set)) { /* close it */ PPTP_CALL * call; retval = vector_search(call_list, i, &call); if (retval) { struct local_callinfo *lci = pptp_call_closure_get(conn, call); log("Closing connection (unhandled)"); if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM); if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM); free(lci); /* soft shutdown. Callback will do hard shutdown later */ pptp_call_close(conn, call); vector_remove(call_list, i); } FD_CLR(i, &call_set); close(i); } } while (vector_size(call_list) > 0 || first); shutdown: { int rc; fd_set read_set, write_set; struct timeval tv; signal(SIGINT, callmgr_do_nothing); signal(SIGTERM, callmgr_do_nothing); /* warn("Shutdown"); */ /* kill all open calls */ for (i = 0; i < vector_size(call_list); i++) { PPTP_CALL *call = vector_get_Nth(call_list, i); struct local_callinfo *lci = pptp_call_closure_get(conn, call); log("Closing connection (shutdown)"); pptp_call_close(conn, call); if(lci->pid[0] > 1) kill(lci->pid[0], SIGTERM); if(lci->pid[1] > 1) kill(lci->pid[1], SIGTERM); } /* attempt to dispatch these messages */ FD_ZERO(&read_set); FD_ZERO(&write_set); pptp_fd_set(conn, &read_set, &write_set, &max_fd); tv.tv_sec = 0; tv.tv_usec = 0; select(max_fd + 1, &read_set, &write_set, NULL, &tv); rc = pptp_dispatch(conn, &read_set, &write_set); if (rc > 0) { /* wait for a respond, a timeout because there might not be one */ FD_ZERO(&read_set); FD_ZERO(&write_set); pptp_fd_set(conn, &read_set, &write_set, &max_fd); tv.tv_sec = 2; tv.tv_usec = 0; select(max_fd + 1, &read_set, &write_set, NULL, &tv); rc = pptp_dispatch(conn, &read_set, &write_set); if (rc > 0) { if (i > 0) sleep(2); /* no more open calls. Close the connection. */ pptp_conn_close(conn, PPTP_STOP_LOCAL_SHUTDOWN); /* wait for a respond, a timeout because there might not be one */ FD_ZERO(&read_set); FD_ZERO(&write_set); pptp_fd_set(conn, &read_set, &write_set, &max_fd); tv.tv_sec = 2; tv.tv_usec = 0; select(max_fd + 1, &read_set, &write_set, NULL, &tv); pptp_dispatch(conn, &read_set, &write_set); if (rc > 0) sleep(2); } } /* with extreme prejudice */ pptp_conn_destroy(conn); vector_destroy(call_list); } cleanup: signal(SIGINT, callmgr_do_nothing); signal(SIGTERM, callmgr_do_nothing); close_inetsock(inet_sock, inetaddr); close_unixsock(unix_sock, inetaddr); return 0; }
int main(int argc, char* argv[]) { int i , maxi , maxfd , listenfd , connfd , sockfd ; int nready , client[ FD_SETSIZE ] ; ssize_t n ; fd_set rset , allset ; char buf [ MAXLINE ]; socklen_t clilen ; struct sockaddr_in cliaddr , servaddr ; //creat socket listenfd = socket( AF_INET , SOCK_STREAM , 0 ); //set socket bzero(&servaddr , sizeof( servaddr )); servaddr.sin_family = AF_INET ; servaddr.sin_addr.s_addr = htonl( INADDR_ANY ); servaddr.sin_port = htons( SERV_PORT ) ; //bind port bind(listenfd , (SA*) &servaddr ,sizeof(servaddr) ); //listen port listenfd listen(listenfd , 10 ); // max client is 10 //consider maxfd maxfd = listenfd ; //initial maxi which is num of fd maxi = -1; //all client port is closed now for(i = 0; i < FD_SETSIZE ; i++) client[i] = -1 ; //initial select set FD_ZERO(&allset); //wait listenfd which is in allset when select FD_SET(listenfd , &allset ); printf("ready to wait \n listenfd=%d",listenfd); for(;;) { rset = allset ; //nready is the fd ready to ready nready = select( maxfd + 1 , &rset , NULL , NULL , NULL ); if(FD_ISSET(listenfd , &rset) ){ //connect to ready client clilen = sizeof( cliaddr ) ; connfd = accept( listenfd , (SA* )&cliaddr , &clilen ); printf("start to read: \n"); //sav fd to client[i] for(i = 0 ; i<FD_SETSIZE; i++){ if(client[i]<0) { client[i] = connfd; break; } } //if full, exit if(i == FD_SETSIZE){ printf("too many client\n"); exit(0); } //wait connfd when select FD_SET(connfd, &allset); if(connfd > maxfd )maxfd = connfd; if(i > maxi )maxi = i; if(--nready <= 0)continue; } //seek connected socket for(i=0;i<=maxi;i++){ if( (sockfd = client[i]) < 0 )continue; if(FD_ISSET(sockfd,&rset)){ if((n = readline(sockfd , buf , MAXLINE )) == 0 ) { close(sockfd); FD_CLR(sockfd , &allset ); client[i] = -1; } else if(n>0){ int k; //write messege to all client printf("%s",buf); for(k=0;k<=maxi;k++){ if(client[k]!=-1){ printf("write in k=%d\n",k); if((write(client[k] , buf , n))!=n)printf("write error!\n"); } } } else if (n<0)printf("error!\n"); if(--nready <= 0) break; } } } }
int main(int argc, char ** argv) { int listenfd, connfd, i, maxindex; int n, nready; int client[MAXCLIENT]; fd_set rset; int maxfds; char buf[MAXLINE]; struct sockaddr_in svraddr, cliaddr; svraddr.sin_family = AF_INET; svraddr.sin_port = htons(SEVR_PORT); svraddr.sin_addr.s_addr = htonl(INADDR_ANY); listenfd = socket(AF_INET, SOCK_STREAM, 0); Bind(listenfd, (struct sockaddr *)&svraddr, sizeof(svraddr)); Listen(listenfd, 17); Signal(SIGCHLD, sig_child); FD_ZERO(&rset); maxfds = listenfd + 1; socklen_t clilen = sizeof(cliaddr); for(i=0; i<MAXCLIENT; i++) client[i] = -1; maxindex = 0; for(;;) { FD_SET(listenfd, &rset); nready = Select(maxfds, &rset, NULL, NULL, NULL); if( FD_ISSET(listenfd, &rset) ) { connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); printf("Accept Connection from %s %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, buf, sizeof(cliaddr)), ntohs(cliaddr.sin_port)); maxfds = MAX(maxfds, connfd) + 1; for(i=0; i<MAXCLIENT; i++) { if( client[i] < 0 ) { client[i] = connfd; break; } } if( i == MAXCLIENT ) err_quit("too many clients"); FD_SET(connfd, &rset); maxfds = MAX(maxfds, connfd) + 1; maxindex = MAX(maxindex, i); //record max index of client valid } for(i=0; i<maxindex; i++) { int sockfd; if( (sockfd = client[i]) < 0 ) //find valid socket fd continue; printf("sockfd = %d\n", sockfd); if( FD_ISSET(sockfd, &rset) ) { printf("client FD_ISSET\n"); if( (n = read(sockfd, buf, MAXLINE)) == 0 ) // read EOF { close(sockfd); FD_CLR(sockfd, &rset); client[i] = -1; } else writen(sockfd, buf, n); } if( -- nready == 0 ) break; //process all readable socket fd } } }
int main() { fd_set master; fd_set read_fds; struct sockaddr_in serveraddr; struct sockaddr_in clientaddr; int fdmax; int listener; int newfd; char buf[5000]; int nbytes; int yes = 1; int addrlen; int i, j; FD_ZERO(&master); FD_ZERO(&read_fds); if((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Server-socket() error "); exit(1); } printf("Server-socket() is OK...\n"); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = INADDR_ANY; serveraddr.sin_port = htons(PORT); memset(&(serveraddr.sin_zero), '\0', 8); if(bind(listener, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) == -1) { perror("Server-bind() error "); exit(1); } printf("Server-bind() is OK...\n"); if(listen(listener, 1000) == -1) { perror("Server-listen() error "); exit(1); } printf("Server-listen() is OK...\n"); FD_SET(listener, &master); fdmax = listener; for(;;) { read_fds = master; if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("Server-select() error lol!"); exit(1); } else { printf("Server-select() is OK...\n"); } for(i = 0; i <= fdmax; i++) { if(FD_ISSET(i, &read_fds)) { if(i == listener) { addrlen = sizeof(clientaddr); if((newfd = accept(listener, (struct sockaddr *)&clientaddr, &addrlen)) == -1) { perror("Server-accept() error"); } else { printf("Server-accept() is OK...\n"); FD_SET(newfd, &master); if(newfd > fdmax) { fdmax = newfd; } printf("%s: New connection on socket %d\n", inet_ntoa(clientaddr.sin_addr), newfd); } } else { if((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) { if(nbytes == 0) printf("socket %d hung up\n", i); else perror("recv() error"); close(i); FD_CLR(i, &master); } else { for(j = 0; j <= fdmax; j++) { if(FD_ISSET(j, &master)) { if(j != listener && j != i) { if(send(j, buf, nbytes, 0) == -1) perror("send() error"); } } } } } } } } return 0; }
main(int argc,char *argv[]) #endif { int listener_fd, new_fd; int remotelen; int port = 0; int c, on; struct sockaddr_in local_sin, remote_sin; static fd_set fdset, fdset_saved; struct conn_stat *rconn, *wconn; #ifdef STE_WINDOWS u_long param = 0; /* FIONBIO コマンドのパラメータ Non-Blocking ON*/ int nRtn; WSADATA wsaData; stehubstat_t stehubstat[1]; nRtn = WSAStartup(MAKEWORD(1, 1), &wsaData); #endif while ((c = getopt(argc, argv, "p:d:")) != EOF){ switch (c) { case 'p': port = atoi(optarg); break; case 'd': debuglevel = atoi(optarg); break; default: print_usage(argv[0]); } } conn_stat_head->next = NULL; conn_stat_head->fd = 0; if(( listener_fd = socket( AF_INET, SOCK_STREAM,0 )) < 0 ) { SET_ERRNO(); print_err(LOG_ERR,"socket: %s (%d)\n", strerror(errno), errno); exit(1); } on = 1; if((setsockopt(listener_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on))) <0){ SET_ERRNO(); print_err(LOG_ERR,"setsockopt:%s\n", strerror(errno)); exit(1); } if(port == 0) port = PORT_NO; memset((char *)&remote_sin, 0x0, sizeof(struct sockaddr_in)); memset((char *)&local_sin, 0x0, sizeof(struct sockaddr_in)); local_sin.sin_port = htons((short)port); local_sin.sin_family = AF_INET; local_sin.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(listener_fd,(struct sockaddr *)&local_sin,sizeof(struct sockaddr_in)) < 0 ){ SET_ERRNO(); print_err(LOG_ERR,"bind:%s\n", strerror(errno)); exit(1); } /* * accept() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if( fcntl (listener_fd, F_SETFL, O_NONBLOCK) < 0) { #else if( ioctlsocket(listener_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "Failed to set nonblock: %s (%d)\n",strerror(errno), errno); exit(1); } if(listen(listener_fd, 5) < 0) { SET_ERRNO(); print_err(LOG_ERR,"listen:%s\n", strerror(errno)); exit(1); } FD_ZERO(&fdset_saved); FD_SET(listener_fd, &fdset_saved); /* * syslog のための設定。Facility は LOG_USER とする * Windows の場合はログファイルをオープンする。 */ #ifdef STE_WINDOWS hStedLog = CreateFile(STEHUB_LOG_FILE, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ| FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); SetFilePointer(hStedLog, 0, NULL, FILE_END); if(isTerminal == FALSE){ /* サービスとして呼ばれている(コマンドプロンプトから呼ばれていない)場合 */ stehubServiceStatus.dwServiceType = SERVICE_WIN32; stehubServiceStatus.dwCurrentState = SERVICE_START_PENDING; stehubServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwServiceSpecificExitCode = 0; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; /* サービスコントロールハンドラーを登録 */ stehubServiceStatusHandle = RegisterServiceCtrlHandlerEx( "Stehub", //LPCTSTR stehub_svc_ctrl_handler, //LPHANDLER_FUNCTION_EX (LPVOID)stehubstat //LPVOID ); if (stehubServiceStatusHandle == (SERVICE_STATUS_HANDLE)0){ return; } stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; if (!SetServiceStatus (stehubServiceStatusHandle, &stehubServiceStatus)){ // SetServiceStatus が失敗した場合の処理・・ print_err(LOG_ERR, "SetServiceStatus Failed\n"); } } #else openlog(basename(argv[0]),LOG_PID,LOG_USER); #endif /* * ここまではとりあえず、フォアグラウンドで実行。 * ここからは、デバッグレベル 0 (デフォルト)なら、バックグラウンド * で実行し、そうでなければフォアグラウンド続行。 * Windows の場合は、いづれにしてもフォアグラウンドで実行 * し、デバッグレベル 1 以上の場合はログをファイルに書く。 */ if (debuglevel == 0){ #ifndef STE_WINDOWS print_err(LOG_NOTICE,"Going to background mode\n"); if(become_daemon() != 0){ print_err(LOG_ERR,"can't become daemon\n"); print_err(LOG_ERR,"Exit\n"); exit(1); } #else use_log = 1; #endif } print_err(LOG_NOTICE,"Started\n"); /* * メインループ * 仮想 NIC デーモンからの接続要求を待ち、接続後は仮想 NIC デーモン * からのデータを待つ。1つの仮想デーモンからのデータを他方に転送する。 */ for(;;){ fdset = fdset_saved; if( select(FD_SETSIZE, &fdset, NULL, NULL, NULL) < 0){ SET_ERRNO(); print_err(LOG_ERR,"select:%s\n", strerror(errno)); } if(FD_ISSET(listener_fd, &fdset)){ remotelen = sizeof(struct sockaddr_in); if((new_fd = accept(listener_fd,(struct sockaddr *)&remote_sin, &remotelen)) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK || errno == ECONNABORTED){ print_err(LOG_NOTICE, "accept: %s\n", strerror(errno)); continue; } else { print_err(LOG_ERR, "accept: %s\n", strerror(errno)); return(-1); } } FD_SET(new_fd, &fdset_saved); print_err(LOG_NOTICE,"fd%d: connection from %s\n",new_fd, inet_ntoa(remote_sin.sin_addr)); add_conn_stat(new_fd, remote_sin.sin_addr); /* * recv() でブロックされるのを防ぐため、non-blocking mode に設定 */ #ifndef STE_WINDOWS if (fcntl(new_fd, F_SETFL, O_NONBLOCK) < 0 ) { #else if(ioctlsocket(new_fd, FIONBIO, ¶m) < 0){ #endif SET_ERRNO(); print_err(LOG_ERR, "fd%d: Failed to set nonblock: %s (%d)\n", new_fd,strerror(errno),errno); return(-1); } continue; } for( rconn = conn_stat_head->next ; rconn != NULL ; rconn = rconn->next){ int rfd, wfd; rfd = rconn->fd; if (FD_ISSET(rfd, &fdset)){ int rsize; char databuf[SOCKBUFSIZE]; char *bufp; int datalen; bufp = (char *)databuf; rsize = recv(rfd, bufp, SOCKBUFSIZE,0); if(rsize == 0){ /* * コネクションが切断されたようだ。 * socket を close してループを抜ける */ print_err(LOG_ERR,"fd%d: Connection closed by %s\n", rfd, inet_ntoa(rconn->addr)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } if(rsize < 0){ SET_ERRNO(); /* * 致命的でない error の場合は無視してループを継続 */ if(errno == EINTR || errno == EWOULDBLOCK){ print_err(LOG_NOTICE, "fd%d: recv: %s\n", rfd, strerror(errno)); continue; } /* * エラーが発生したようだ。 * socket を close して forループを抜ける */ print_err(LOG_ERR,"fd%d: recv: %s\n", rfd,strerror(errno)); CLOSE(rfd); print_err(LOG_ERR,"fd%d: closed\n", rfd); FD_CLR(rfd, &fdset_saved); delete_conn_stat(rfd); break; } /* * 他の仮想 NIC にパケットを転送する。 * 「待ち」が発生すると、パフォーマンスに影響があるので、EWOULDBLOCK * の場合は配送をあきらめる。 */ for(wconn = conn_stat_head->next ; wconn != NULL ; wconn = wconn->next){ wfd = wconn->fd; if (rfd == wfd) continue; if( debuglevel > 1){ print_err(LOG_ERR,"fd%d(%s) ==> ", rfd, inet_ntoa(rconn->addr)); print_err(LOG_ERR,"fd%d(%s)\n", wfd,inet_ntoa(wconn->addr)); } if ( send(wfd, bufp, rsize, 0) < 0){ SET_ERRNO(); if(errno == EINTR || errno == EWOULDBLOCK ){ print_err(LOG_NOTICE,"fd%d: send: %s\n", wfd ,strerror(errno)); continue; } else { print_err(LOG_ERR,"fd%d: send: %s (%d)\n",wfd,strerror(errno), errno); CLOSE(wfd); print_err(LOG_ERR,"fd%d: closed\n", wfd); FD_CLR(wfd, &fdset_saved); delete_conn_stat(wfd); break; } } } /* End of loop for send()ing */ } } /* End of loop for each connection */ } /* End of main loop */ } #ifdef STE_WINDOWS /************************************************************************** * Windows の場合の main() * * 引数が -I もしくは -U だった場合には本プログラム(仮想 HUB デーモン) * を Windows のサービスとして登録/登録解除する。 * それ以外の引数が渡された場合には ste_svc_main() を直接呼び出し、引数も * そのまま ste_svc_main() に渡す。 * * 引数(argvとして): * * -I : サービスとして登録。 * -U : 登録解除 * **************************************************************************/ int WINAPIV main(int argc, char *argv[]) { int c; SERVICE_TABLE_ENTRY DispatchTable[] = { { "Stehub", stehub_svc_main}, { NULL, NULL } }; isTerminal = _isatty(_fileno(stdout))? TRUE:FALSE; // // 引数が無ない場合。 // コマンドプロンプトから呼ばれた時は stehub_svc_main() を呼び、 // そうでなければ StartServiceCtlDispatcher() を呼ぶ。 // if(argc == 1 ){ if(isTerminal == TRUE){ stehub_svc_main(argc, argv); return(0); } else { StartServiceCtrlDispatcher(DispatchTable); return(0); } } while((c = getopt(argc, argv, "IU")) != EOF ){ switch(c){ case 'I': // stehub.exe をサービスとして登録 if(stehub_install_svc()) printf("Service Installed Sucessfully\n"); else printf("Error Installing Service\n"); break; case 'U': // stehub.exe のサービスとして登録を解除 if(stehub_delete_svc()) printf("Service UnInstalled Sucessfully\n"); else printf("Error UnInstalling Service\n"); break; default : // // 引数が -U、-I でなければコマンドプロンプト内で // stehub.exe を起動したいのだと判断し、引数を全て // stehub_svc_main() に渡して呼び出す。 // stehub_svc_main(argc, argv); return(0); } } return(0); } /**************************************** * Windows サービス登録ルーチン * ****************************************/ BOOL stehub_install_svc() { LPCTSTR lpszBinaryPathName; TCHAR strDir[1024]; HANDLE schSCManager,schService; GetCurrentDirectory(1024, strDir); strcat((char *)strDir, "\\stehub.exe"); schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; lpszBinaryPathName=strDir; schService = CreateService(schSCManager,"Stehub", "Stehub Virtual HUB daemon", // 表示用サービス名 SERVICE_ALL_ACCESS, // アクセス SERVICE_WIN32_OWN_PROCESS, // サービスタイプ SERVICE_DEMAND_START, // スタートタイプ SERVICE_ERROR_NORMAL, // エラーコントロールタイプ lpszBinaryPathName, // バイナリへのパス NULL, // No load ordering group NULL, // No tag identifier NULL, // No dependencies NULL, // LocalSystem account NULL);// No password if (schService == NULL) return FALSE; CloseServiceHandle(schService); return TRUE; } /**************************************** * Windows サービス登録解除ルーチン * ****************************************/ BOOL stehub_delete_svc() { HANDLE schSCManager; SC_HANDLE hService; schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) return FALSE; hService=OpenService(schSCManager, "Stehub", SERVICE_ALL_ACCESS); if (hService == NULL) return FALSE; if(DeleteService(hService)==0) return FALSE; if(CloseServiceHandle(hService)==0) return FALSE; return TRUE; } /****************************************************************************** * stehub_svc_ctrl_handler() * * サービスステータスハンドラー * DEVICEEVENT を拾うためには Handler ではなく、HandlerEx じゃないといけないらしい。 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/handlerex.asp * * まったく呼ばれていないような・・? ******************************************************************************/ DWORD WINAPI stehub_svc_ctrl_handler( DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext ) { PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lpEventData; WPARAM wParam = (WPARAM) dwEventType; stehubstat_t *stehubstat = NULL; stehubstat = (stehubstat_t *)lpContext; if(debuglevel > 1){ print_err(LOG_DEBUG, "Service Status Handler stehub_svc_ctrl_handler called\n"); } switch(dwControl){ case SERVICE_CONTROL_DEVICEEVENT: break; case SERVICE_CONTROL_PAUSE: stehubServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: stehubServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: stehubServiceStatus.dwWin32ExitCode = 0; stehubServiceStatus.dwCurrentState = SERVICE_STOPPED; stehubServiceStatus.dwCheckPoint = 0; stehubServiceStatus.dwWaitHint = 0; SetServiceStatus (stehubServiceStatusHandle,&stehubServiceStatus); break; case SERVICE_CONTROL_INTERROGATE: break; } return NO_ERROR; }
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, const apr_pollfd_t *descriptor) { apr_uint32_t i; #ifndef HAVE_POLL apr_os_sock_t fd; #endif #ifdef HAVE_POLL for (i = 0; i < pollset->nelts; i++) { if (descriptor->desc.s == pollset->query_set[i].desc.s) { /* Found an instance of the fd: remove this and any other copies */ apr_uint32_t dst = i; apr_uint32_t old_nelts = pollset->nelts; pollset->nelts--; for (i++; i < old_nelts; i++) { if (descriptor->desc.s == pollset->query_set[i].desc.s) { pollset->nelts--; } else { pollset->pollset[dst] = pollset->pollset[i]; pollset->query_set[dst] = pollset->query_set[i]; dst++; } } return APR_SUCCESS; } } #else /* no poll */ if (descriptor->desc_type == APR_POLL_SOCKET) { fd = descriptor->desc.s->socketdes; } else { #if !APR_FILES_AS_SOCKETS return APR_EBADF; #else fd = descriptor->desc.f->filedes; #endif } for (i = 0; i < pollset->nelts; i++) { if (descriptor->desc.s == pollset->query_set[i].desc.s) { /* Found an instance of the fd: remove this and any other copies */ apr_uint32_t dst = i; apr_uint32_t old_nelts = pollset->nelts; pollset->nelts--; for (i++; i < old_nelts; i++) { if (descriptor->desc.s == pollset->query_set[i].desc.s) { pollset->nelts--; } else { pollset->query_set[dst] = pollset->query_set[i]; dst++; } } FD_CLR(fd, &(pollset->readset)); FD_CLR(fd, &(pollset->writeset)); FD_CLR(fd, &(pollset->exceptset)); if (((int)fd == pollset->maxfd) && (pollset->maxfd > 0)) { pollset->maxfd--; } return APR_SUCCESS; } } #endif /* no poll */ return APR_NOTFOUND; }
int main() { struct sockaddr_in name; int s; fd_set mask; int recv_s[10]; int valid[10]; fd_set dummy_mask,temp_mask; int i,j,num; int mess_len; int neto_len; char mess_buf[MAX_MESS_LEN]; long on=1; s = socket(AF_INET, SOCK_STREAM, 0); if (s<0) { perror("Net_server: socket"); exit(1); } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) { perror("Net_server: setsockopt error \n"); exit(1); } name.sin_family = AF_INET; name.sin_addr.s_addr = INADDR_ANY; name.sin_port = htons(PORT); if ( bind( s, (struct sockaddr *)&name, sizeof(name) ) < 0 ) { perror("Net_server: bind"); exit(1); } if (listen(s, 4) < 0) { perror("Net_server: listen"); exit(1); } i = 0; int is_first = 0; int no_reception = 0; FILE * fw; struct timeval first, last; gettimeofday(&first, NULL); int total_bytes=0; FD_ZERO(&mask); FD_ZERO(&dummy_mask); FD_SET(s,&mask); for(;;) { temp_mask = mask; num = select( FD_SETSIZE, &temp_mask, &dummy_mask, &dummy_mask, NULL); if (num > 0) { if ( FD_ISSET(s,&temp_mask) ) { recv_s[i] = accept(s, 0, 0) ; FD_SET(recv_s[i], &mask); valid[i] = 1; i++; } for(j=0; j<i ; j++) { if (valid[j]) { if ( FD_ISSET(recv_s[j],&temp_mask) ) { if (is_first == 0) { is_first = 1; int length; if (recv(recv_s[j], &length, sizeof(length),0) > 0) { int strlen = length - sizeof(length); recv(recv_s[j], mess_buf, strlen, 0); mess_buf[strlen] = '\0'; printf("Writing to %s\n", mess_buf); gettimeofday(&first, NULL); fw = fopen(mess_buf, "w"); } } int len = recv(recv_s[j],mess_buf,MAX_MESS_LEN,0); if( len > 0) { no_reception = 0; fwrite(mess_buf, 1, len, fw); total_bytes = total_bytes + len; } else { no_reception++; if (no_reception == 2) { FD_CLR(recv_s[j], &mask); close(recv_s[j]); valid[j]=0; if (fw != NULL) { fclose(fw); } gettimeofday(&last, NULL); double difference = (double)(last.tv_sec - first.tv_sec) + (double)(last.tv_usec - first.tv_usec) / 1000000.0; double total = (double)total_bytes / 1000000.0; printf("Transfer completed. Total Megabytes %f. Total Time %f. Average Rate (Mbits/sec) %f.\n", total, difference, (total*8.0) / difference); exit(1); } } } } } } } return 0; }
int main(){ //создаем именованные каналы в ядре с местом в файловом пространстве имен printf("Создаю именованные каналы...");fflush(stdout); const char *pipe_in="in.fifo", *pipe_out="out.fifo"; unlink(pipe_in); unlink(pipe_out); int res=mkfifo(pipe_in,0666); if(-1==res){ perror("Ошибка создания канала in"); return 1; } res=mkfifo(pipe_out,0666); if(-1==res){ perror("Ошибка создания канала out"); return 2; } printf("ok!\n"); //получаем файловые дескрипторы каналов и переводим в неблокирующий режим (чтение и запись, чтоб не блокировалось здесь же сразу) printf("Получаю файловые дескрипторы..."); int fd_in=open(pipe_in,O_RDWR|O_NONBLOCK); if(-1==fd_in){ perror("Не получен дескриптор in"); return 3; } int fd_out=open(pipe_out,O_RDWR|O_NONBLOCK); if(-1==fd_out){ perror("Не получен дескриптор out"); close(fd_in); return 4; } printf("ok!\n"); //мультиплексирование printf("Мультиплексирование (select):\n"); fd_set set_for_read, set_for_write; //ровно по 1024 бит printf("Цикл:\n"); //узнаем наибольший номер дескриптора, чтоб узнать сколько битов в наборе нужно отслеживать int max=fd_in<fd_out ? fd_out : fd_in; //буфер на сервере (на случай задержки отправки) struct Buf *root=NULL, *tail=NULL; int is_out=0; //запускаем цикл проверки long long cnt=0; while(1){ //инициализация FD_ZERO(&set_for_read); FD_ZERO(&set_for_write); //добавляем в набор отслеживаемый на чтение дескриптор printf("\tдобавляем in..."); FD_SET(fd_in,&set_for_read); printf("ok!\n"); if(is_out){ printf("\tдобавляем out..."); FD_SET(fd_out,&set_for_write); printf("ok!\n"); } fflush(stdout); //запускаем проверку готовности ++cnt; printf("\n%lld)-->select...",cnt);fflush(stdout); select(max+1,&set_for_read,&set_for_write,NULL,NULL);//эта команда сбрасывает не готовые биты поля, поэтому нужно регистрировать поновой printf("ok!\n"); //проснулись if(FD_ISSET(fd_out,&set_for_write)){ //проверка готовности писать printf("-->write..."); if(root==NULL) FD_CLR(fd_out,&set_for_write);//снимаем с регистрации, т.к. нечего писать else{ int len=write(fd_out,root->data,root->len); if(len!=-1){//успешно записано printf("ok!\n"); struct Buf * tmp=root->next; free(root); root=tmp; if(root==NULL){ //все записано tail=NULL; is_out=0; } } } } if(FD_ISSET(fd_in,&set_for_read)){ //проверка готовности чтения printf("-->read..."); //читаем из канала char data[LEN+1]; int len=read(fd_in,data,LEN); if(-1!=len){ if(root==NULL) tail=root=(struct Buf*)malloc(sizeof(struct Buf)); else{ tail->next=(struct Buf*)malloc(sizeof(struct Buf)); tail=tail->next; } tail->next=NULL; tail->len=len; memcpy(tail->data,data,len); data[len]='\0'; printf("ok! data=%s\n",data); //регистрируем дескриптор out is_out=1; } } } //закрываем дескрипторы close(fd_in); close(fd_out); //выносим каналы из фалового пространства unlink(pipe_in); unlink(pipe_out); return 0; }
int main(int argc, char const *argv[]) { if(argc!=2) { printf("Pass the fifo name\n"); exit(1); } //sharing Process Id int k1=ftok(".",1); int shmid=shmget(k1,sizeof(int),0777|IPC_CREAT); if(shmid==-1) { printf("shmget error\n"); exit(1); } int *p; p=shmat(shmid,NULL,0); if(p==(int*)-1) { printf("shmat error\n"); exit(1); } *p=getpid(); signal(SIGUSR1,handler); k1=ftok(".",3); shmid=shmget(k1,30,0777|IPC_CREAT); if(shmid==-1) { printf("shmget 1error\n"); exit(1); } char *p1=shmat(shmid,NULL,0); if(p1==(char*)-1) { printf("shmat error\n"); exit(1); } char *name="/tmp/"; fifo=(char*)malloc(BUF_SIZE); sprintf(fifo,"%s%s",name,argv[1]); int r=mkfifo(fifo,0777); if(r<0) { printf("mkfifo error\n"); exit(1); } strcpy(p1,fifo); //getting fifo name int pfd[5]; k1=ftok(".",2); shmid=shmget(k1,30,0777|IPC_CREAT); if(shmid==-1) { printf("shmget error\n"); exit(1); } char *p2; p2=shmat(shmid,NULL,0); if(p2==(char*)-1) { printf("shmat error\n"); exit(1); } int c=0; int fd[2]; pipe(fd); c=fork(); strcpy(msg,""); if(c>0) { int nfd=4; pfd[0]=0; pfd[1]=open(p2,O_RDONLY); FILE *f=popen("./po","r"); pfd[2]=fileno(f); close(fd[1]); pfd[3]=fd[0]; int i=0,j; while(1) { sleep(1); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; fd_set tr; FD_ZERO(&tr); FD_SET(pfd[i],&tr); //printf("before\n"); int res=select(pfd[i]+1,&tr,NULL,NULL,&tv); //read(pfd[i],buf,BUF_SIZE); //printf("in while %d %d\n",res,i); if(res>0&&FD_ISSET(pfd[i],&tr)) {//printf("inside event %d\n", i); char *buf=(char*)malloc(BUF_SIZE); read(pfd[i],buf,BUF_SIZE); strcat(msg,"\t"); strcat(msg,buf); } FD_CLR(pfd[i],&tr); i=(i+1)%nfd; } } else { close(fd[0]); while(1) { sleep(10); char *m="This is from pipe"; write(fd[1],m,strlen(m)); } } return 0; }
void fe_ipv6_hub_rm_udp6(fe_ipv6_hub *s, fe_udp6 *sock) { if(!FD_ISSET(*sock, &s->read_set)) return; FD_CLR(*sock, &s->read_set); FD_CLR(*sock, &s->ready_set); }
/* * Servers that echoes a Client using I/O Multiplexing */ int main(int argc, char **argv) { // Check arguments if (argc != 2){ printf("Usage: ./echosrv <PORT>\n"); return -1; } // Create the socket int listenfd; if ((listenfd = socket(AF_INET6, SOCK_STREAM, 0)) < 0) { perror("socket\n"); return -1; } // Initialize server sockaddr structure struct sockaddr_in6 servaddr; bzero(&servaddr, sizeof(servaddr)); servaddr.sin6_family = AF_INET6; servaddr.sin6_addr = in6addr_any; servaddr.sin6_port = htons(atoi(argv[1])); if ((bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0) { perror("bind"); return -1; } // Convert the socket to a listening socket if (listen(listenfd, BACKLOG) < 0 ) { perror("listen"); return -1; } // Initialize arguments for the select function int maxfd = listenfd; // Initialize the array of clients int client[FD_SETSIZE]; for (int i = 0; i < FD_SETSIZE; i++) { client[i] = -1; } // Initialize the array of client nicknames int nicknames[FD_SETSIZE][MAXNICK]; // Initialize all descriptors fd_set rset; fd_set allset; FD_ZERO(&allset); FD_SET(listenfd, &allset); // Ready descriptors int ready; int connfd; int sockfd; int i; int n; struct sockaddr_in6 cliaddr; socklen_t clilen = sizeof(cliaddr); char buff[MAXLINE]; char temp[MAXLINE]; char addrbuff[INET6_ADDRSTRLEN]; while (1) { rset = allset; if ((ready = select(maxfd + 1, &rset, NULL, NULL, NULL)) < 0) { perror("select"); return -1; } // Check for new client if (FD_ISSET(listenfd, &rset)) { if ((connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen)) < 0) { perror("accept"); return -1; } // Convert IPv6 address to presentation inet_ntop(AF_INET6, &cliaddr.sin6_addr, addrbuff, INET6_ADDRSTRLEN); printf("Connected client from %s:%d\n", addrbuff, ntohs(cliaddr.sin6_port)); // Save connected socket descriptor in the client array for (i = 0; i < FD_SETSIZE; i++) { if (client[i] < 0) { client[i] = connfd; break; } } // Ragequit on too many requests if (i == FD_SETSIZE) { printf("Too many clients\n"); return -1; } // Add connfd to allset FD_SET(connfd, &allset); if (connfd > maxfd) { maxfd = connfd; } // Check whether there aren't other ready sockets if (--ready <= 0) { continue; } } // Serve clients for (i = 0; i < FD_SETSIZE; i++) { if ((sockfd = client[i]) < 0) { continue; } if (FD_ISSET(sockfd, &rset)) { if ((n = exso_readln(sockfd, buff, MAXLINE)) < 0) { perror("exso_readln"); } else if (n == 0) { // Convert IPv6 address to presentation inet_ntop(AF_INET6, &cliaddr.sin6_addr, addrbuff, INET6_ADDRSTRLEN); printf("Disconnected client from %s:%d\n", addrbuff, ntohs(cliaddr.sin6_port)); close(sockfd); FD_CLR(sockfd, &allset); client[i] = -1; bzero(nicknames[i], MAXNICK); } else { if (nicknames[i][0] == 0) { if (strncmp(buff, "/nickname", 9) == 0) { sscanf(buff, "/nickname %s\n", nicknames[i]); sprintf(buff, "%s has joined the chat\n", nicknames[i]); } else { sprintf(buff, "Error, expecting /nickname <NICKNAME>\n"); exso_writen(client[i], buff, strlen(buff)); continue; } } else { sprintf(temp, "%s: %s", nicknames[i], buff); sprintf(buff, "%s", temp); } for (i = 0; i < FD_SETSIZE; i++) { if (sockfd == client[i] || client[i] == -1) { continue; } if (exso_writen(client[i], buff, strlen(buff)) < 0) { perror("exso_writen"); } } } // Check whether there aren't other ready sockets if (--ready <= 0) { break; } } } } }
void loop(void) { int i, n, maxfd, maxi, listenfd, clifd, nread; char buf[MAXLINE]; uid_t uid; fd_set rset, allset; FD_ZERO(&allset); if((listenfd = serv_listen(CS_OPEN))<0) { printf("serv_listen error\n"); exit(2); } FD_SET(listenfd, &allset); maxfd = listenfd; maxi = -1; for(;;){ rset = allset; if((n = select(maxfd + 1, &rset, NULL, NULL, NULL))<0) { printf("select error\n"); exit(2); } if(FD_ISSET(listenfd, &rset)){ if((clifd = serv_accept(listenfd, &uid))<0) { printf("serv accept error: %d\n", clifd); exit(2); } i = client_add(clifd, uid); FD_SET(clifd, &allset); if(clifd > maxfd) maxfd = clifd; if(i > maxi) maxi = i; printf("new connection: uid %d, fd %d", uid, clifd); continue; } for(i = 0; i<=maxi; i++){ if((clifd = client[i].fd) < 0) continue; if(FD_ISSET(clifd, &rset)){ if((nread = read(clifd, buf, MAXLINE)) < 0){ printf("read error on fd %d", clifd); exit(2); } else if(nread == 0) { printf("closed: uid %d, fd %d", client[i].uid, clifd); client_del(clifd); FD_CLR(clifd, &allset); close(clifd); } else { handle_request(buf, nread, clifd, client[i].uid); } } } } }
void * socket_thread_fct ( void *arg) { int ret; struct sockaddr_in si_me; socket_data_t *socket_data; int retry = SOCKET_NB_CONNECT_RETRY; /* * master file descriptor list */ fd_set master_fds; /* * temp file descriptor list for select() */ fd_set read_fds; int fd_max = 0; struct timeval tv; socket_data = (socket_data_t *) arg; g_assert (socket_data != NULL); /* * Preparing the socket */ if ((socket_data->sd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { g_warning ("socket failed: %s", g_strerror (errno)); free (socket_data->ip_address); free (socket_data); pthread_exit (NULL); } memset ((void *)&si_me, 0, sizeof (si_me)); si_me.sin_family = AF_INET; si_me.sin_port = htons (socket_data->port); if (inet_aton (socket_data->ip_address, &si_me.sin_addr) == 0) { g_warning ("inet_aton() failed\n"); free (socket_data->ip_address); free (socket_data); pthread_exit (NULL); } /* * clear the master and temp sets */ FD_ZERO (&master_fds); FD_ZERO (&read_fds); /* * Add the GUI pipe to the list of sockets to monitor */ FD_SET (socket_data->pipe_fd, &master_fds); /* * Add the client socket to the list of sockets to monitor */ FD_SET (socket_data->sd, &master_fds); /* * Update the fd_max with the MAX of socket/pipe */ fd_max = MAX (socket_data->pipe_fd, socket_data->sd); /* * Setup the timeout for select. * * * When a timeout is caught, check for new notifications to send to GUI. */ tv.tv_sec = 0; tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; do { /* * Connecting to remote peer */ ret = connect (socket_data->sd, (struct sockaddr *)&si_me, sizeof (struct sockaddr_in)); if (ret < 0) { if ((socket_abort_connection) || (retry < 0)) { if (retry < 0) { g_warning ("Failed to connect to peer %s:%d", socket_data->ip_address, socket_data->port); ui_pipe_write_message (socket_data->pipe_fd, UI_PIPE_CONNECTION_FAILED, NULL, 0); } free (socket_data->ip_address); free (socket_data); socket_abort_connection = FALSE; /* * Quit the thread */ pthread_exit (NULL); } usleep (SOCKET_US_BEFORE_CONNECT_RETRY); retry--; } } while (ret < 0); /* * Set the socket as non-blocking */ fcntl (socket_data->sd, F_SETFL, O_NONBLOCK); while (1) { memcpy (&read_fds, &master_fds, sizeof (master_fds)); ret = select (fd_max + 1, &read_fds, NULL, NULL, &tv); if (ret < 0) { g_warning ("Error in select: %s", g_strerror (errno)); free (socket_data->ip_address); free (socket_data); /* * Quit the thread */ pthread_exit (NULL); } else if (ret == 0) { /* * Timeout for select: check if there is new incoming messages * * * since last GUI update */ if (socket_data->nb_signals_since_last_update > 0) { g_debug ("Timout on select and data new signal in list"); g_debug ("-> notify GUI"); socket_notify_gui_update (socket_data); } /* * Reset the timeval to the max value */ tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; } /* * Checking if there is data to read from the pipe */ if (FD_ISSET (socket_data->pipe_fd, &read_fds)) { FD_CLR (socket_data->pipe_fd, &read_fds); pipe_read_message (socket_data); } /* * Checking if there is data to read from the socket */ if (FD_ISSET (socket_data->sd, &read_fds)) { FD_CLR (socket_data->sd, &read_fds); socket_read (socket_data); /* * Update the timeout of select if there is data not notify to GUI */ if (socket_data->nb_signals_since_last_update > 0) { gint64 current_time; current_time = g_get_monotonic_time (); if ((current_time - socket_data->last_data_notification) > SOCKET_MS_BEFORE_SIGNALLING) { socket_notify_gui_update (socket_data); tv.tv_usec = 1000 * SOCKET_MS_BEFORE_SIGNALLING; } else { /* * Update tv */ tv.tv_usec = (1000 * SOCKET_MS_BEFORE_SIGNALLING) - (current_time - socket_data->last_data_notification); } } } } return NULL; }
int main(void) { fd_set master; // master file descriptor list fd_set read_fds; // temp file descriptor list for select() int fdmax; // maximum file descriptor number int listener; // listening socket descriptor int newfd; // newly accept()ed socket descriptor struct sockaddr_storage remoteaddr; // client address socklen_t addrlen; char buf[256]; // buffer for client data uint32_t recvId; int nbytes; int talking[100]= {0}; //talk to who pairs char remoteIP[INET6_ADDRSTRLEN]; int yes=1; // for setsockopt() SO_REUSEADDR, below int i, j, rv; struct addrinfo hints, *ai, *p; FD_ZERO(&master); // clear the master and temp sets FD_ZERO(&read_fds); // get us a socket and bind it memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if ((rv = getaddrinfo(NULL, PORT, &hints, &ai)) != 0) { fprintf(stderr, "selectserver: %s\n", gai_strerror(rv)); exit(1); } for(p = ai; p != NULL; p = p->ai_next) { listener = socket(p->ai_family, p->ai_socktype, p->ai_protocol); if (listener < 0) { continue; } // lose the pesky "address already in use" error message setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); if (bind(listener, p->ai_addr, p->ai_addrlen) < 0) { close(listener); continue; } break; } // if we got here, it means we didn't get bound if (p == NULL) { fprintf(stderr, "selectserver: failed to bind\n"); exit(2); } freeaddrinfo(ai); // all done with this // listen if (listen(listener, 10) == -1) { perror("listen"); exit(3); } printf("server: waiting for connections...\n"); // add the listener to the master set FD_SET(listener, &master); // keep track of the biggest file descriptor fdmax = listener; // so far, it's this one // main loop for(;;) { read_fds = master; // copy it if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } // run through the existing connections looking for data to read for(i = 0; i <= fdmax; i++) { if (FD_ISSET(i, &read_fds)) { // we got one!! if (i == listener) { // handle new connections addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); if (newfd == -1) { perror("accept"); } else { FD_SET(newfd, &master); // add to master set if (newfd > fdmax) { // keep track of the max fdmax = newfd; } printf("selectserver: new connection from %s on " "socket %d\n", inet_ntop(remoteaddr.ss_family, get_in_addr((struct sockaddr*)&remoteaddr), remoteIP, INET6_ADDRSTRLEN), newfd); //ask who to talk to char *str="you're online now\n"; send(newfd, str, strlen(str), 0); //show list //send mesage to someone } } else { // handle data from a client //recv //switch cmd //show -> list all //talk -> get id, and pair with each other if ((nbytes = recv(i, &buf, sizeof buf, 0)) <= 0) { // got error or connection closed by client if (nbytes == 0) { // connection closed printf("selectserver: socket %d hung up\n", i); } else { perror("recv"); } close(i); // bye! FD_CLR(i, &master); // remove from master set } else { // split cmd char *cmd; cmd= strtok(buf, " "); if (strncmp(cmd, "show",4) == 0) { listUsers(i,j, fdmax, master, listener); } else if (strncmp(cmd, "talk",4) == 0) { cmd= strtok(NULL, " "); //get the userId int userId= atoi(cmd); //get the msg char *msg= strtok(NULL, " "); //send the msg if (FD_ISSET(userId, &master)) { // except the listener and ourselves if (send(userId, msg, strlen(msg), 0) == -1) { perror("send"); } } } else { } } } // END handle data from client } // END got new incoming connection } // END looping through file descriptors } // END for(;;)--and you thought it would never end! return 0; }
int main(int argc, char **argv) { #ifndef THREADED fd_set rfds, wfds, efds; int processed=0; #endif char buffer[4096]; char p[2048]; #ifdef YCA char *cert=0; char appId[64]; #endif int bufoff = 0; int flags, i; FILE *fh; if (argc < 2) { fprintf(stderr, "USAGE %s zookeeper_host_list [clientid_file|cmd:(ls|ls2|create|create2|od|...)]\n", argv[0]); fprintf(stderr, "Version: ZooKeeper cli (c client) version %d.%d.%d\n", ZOO_MAJOR_VERSION, ZOO_MINOR_VERSION, ZOO_PATCH_VERSION); return 2; } if (argc > 2) { if(strncmp("cmd:",argv[2],4)==0){ size_t cmdlen = strlen(argv[2]); if (cmdlen > sizeof(cmd)) { fprintf(stderr, "Command length %zu exceeds max length of %zu\n", cmdlen, sizeof(cmd)); return 2; } strncpy(cmd, argv[2]+4, sizeof(cmd)); batchMode=1; fprintf(stderr,"Batch mode: %s\n",cmd); }else{ clientIdFile = argv[2]; fh = fopen(clientIdFile, "r"); if (fh) { if (fread(&myid, sizeof(myid), 1, fh) != sizeof(myid)) { memset(&myid, 0, sizeof(myid)); } fclose(fh); } } } flags = 0; for (i = 1; i < argc; ++i) { if (strcmp("-r", argv[i]) == 0) { flags = ZOO_READONLY; break; } } #ifdef YCA strcpy(appId,"yahoo.example.yca_test"); cert = yca_get_cert_once(appId); if(cert!=0) { fprintf(stderr,"Certificate for appid [%s] is [%s]\n",appId,cert); strncpy(p,cert,sizeof(p)-1); free(cert); } else { fprintf(stderr,"Certificate for appid [%s] not found\n",appId); strcpy(p,"dummy"); } #else strcpy(p, "dummy"); #endif verbose = 0; zoo_set_debug_level(ZOO_LOG_LEVEL_WARN); zoo_deterministic_conn_order(1); // enable deterministic order hostPort = argv[1]; zh = zookeeper_init(hostPort, watcher, 30000, &myid, NULL, flags); if (!zh) { return errno; } #ifdef YCA if(zoo_add_auth(zh,"yca",p,strlen(p),0,0)!=ZOK) return 2; #endif #ifdef THREADED while(!shutdownThisThing) { int rc; int len = sizeof(buffer) - bufoff -1; if (len <= 0) { fprintf(stderr, "Can't handle lines that long!\n"); exit(2); } rc = read(0, buffer+bufoff, len); if (rc <= 0) { fprintf(stderr, "bye\n"); shutdownThisThing=1; break; } bufoff += rc; buffer[bufoff] = '\0'; while (strchr(buffer, '\n')) { char *ptr = strchr(buffer, '\n'); *ptr = '\0'; processline(buffer); ptr++; memmove(buffer, ptr, strlen(ptr)+1); bufoff = 0; } } #else FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds); while (!shutdownThisThing) { int fd; int interest; int events; struct timeval tv; int rc; zookeeper_interest(zh, &fd, &interest, &tv); if (fd != -1) { if (interest&ZOOKEEPER_READ) { FD_SET(fd, &rfds); } else { FD_CLR(fd, &rfds); } if (interest&ZOOKEEPER_WRITE) { FD_SET(fd, &wfds); } else { FD_CLR(fd, &wfds); } } else { fd = 0; } FD_SET(0, &rfds); rc = select(fd+1, &rfds, &wfds, &efds, &tv); events = 0; if (rc > 0) { if (FD_ISSET(fd, &rfds)) { events |= ZOOKEEPER_READ; } if (FD_ISSET(fd, &wfds)) { events |= ZOOKEEPER_WRITE; } } if(batchMode && processed==0){ //batch mode processline(cmd); processed=1; } if (!processed && FD_ISSET(0, &rfds)) { int rc; int len = sizeof(buffer) - bufoff -1; if (len <= 0) { fprintf(stderr, "Can't handle lines that long!\n"); exit(2); } rc = read(0, buffer+bufoff, len); if (rc <= 0) { fprintf(stderr, "bye\n"); break; } bufoff += rc; buffer[bufoff] = '\0'; while (strchr(buffer, '\n')) { char *ptr = strchr(buffer, '\n'); *ptr = '\0'; processline(buffer); ptr++; memmove(buffer, ptr, strlen(ptr)+1); bufoff = 0; } } zookeeper_process(zh, events); } #endif if (to_send!=0) fprintf(stderr,"Recvd %d responses for %d requests sent\n",recvd,sent); zookeeper_close(zh); return 0; }
int main() { struct sockaddr_in sa_udp, sa_recv, sa_client, sa_udp_cl; socklen_t sa_udp_len = sizeof(struct sockaddr_in); socklen_t sa_recv_len = sa_udp_len; socklen_t sa_client_len = sa_udp_len; socklen_t sa_udp_cl_len = sa_udp_len; int udp_sock, recv_sock, client_sock, maxfd = -1; int udp_port = 47624, recv_port = 2350; unsigned char temp[512]; int i, ret = 0; fd_set recv_set, master_set; FD_ZERO(&recv_set); FD_ZERO(&master_set); memset(&sa_udp, 0, sa_udp_len); memset(&sa_recv, 0, sa_recv_len); memset(&sa_client, 0, sa_client_len); memset(&sa_udp_cl, 0, sa_udp_cl_len); printf("Listening on udp port %d\n", udp_port); sa_udp.sin_family = AF_INET; sa_udp.sin_port = htons(udp_port); sa_udp.sin_addr.s_addr = htonl(INADDR_ANY); if((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { perror("socket"); exit(1); } maxfd = max(maxfd, udp_sock); if(bind(udp_sock, (struct sockaddr *)&sa_udp, sa_udp_len) < 0) { perror("bind"); exit(2); } FD_SET(udp_sock, &master_set); printf("Listening on tcp port %d\n", recv_port); sa_recv.sin_family = AF_INET; sa_recv.sin_port = htons(recv_port); sa_recv.sin_addr.s_addr = htonl(INADDR_ANY); if((recv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_IP)) < 0) { perror("socket"); exit(3); } maxfd = max(maxfd, recv_sock); if(bind(recv_sock, (struct sockaddr*)&sa_recv, sa_recv_len) < 0) { perror("bind"); exit(4); } if(listen(recv_sock, 5)< 0) { perror("listen"); exit(5); } FD_SET(recv_sock, &master_set); signal(SIGINT, signal_handler); puts("Starting up the select loop."); for(;;) { recv_set = master_set; if(select(maxfd+1, &recv_set, NULL, NULL, NULL) < 0) { perror("select"); exit(6); } for(i = 0; i <= maxfd; ++i) { if(FD_ISSET(i, &recv_set)) { if(i == udp_sock) { int recv_len; printf("Got an udp packet!\n"); if((recv_len = recvfrom(udp_sock, temp, 512, 0, (struct sockaddr *)&sa_udp_cl, &sa_udp_cl_len)) < 0) { perror("recvfrom"); exit(8); } if(handleSocketBroadcast(temp, recv_len, &sa_udp_cl, sa_udp_cl_len, &sa_recv) != 0) { fprintf(stderr, "Something bad happened in handleSocketBroadcast\n"); } /* just throw away the rest of the data */ if(recv_len == 512) recvfrom(udp_sock, temp, 512, 0, (struct sockaddr *)&sa_udp_cl, &sa_udp_cl_len); }else if(i == recv_sock) { printf("Got a tcp packet on the server port\n"); if((client_sock = accept(recv_sock, (struct sockaddr *)&sa_client, &sa_client_len)) < 0) { perror("accept"); exit(7); } else { FD_SET(client_sock, &master_set); maxfd = max(maxfd, client_sock); } } else { int recv_len; if((recv_len = recv(i, temp, 512, 0)) < 0) { perror("recv"); exit(8); } if(recv_len == 0) { puts("Client closed socket"); } close(i); FD_CLR(i, &master_set); } } } } return ret; }
int main (int argc, char **argv) { #ifdef HAVE_LUA /* Lua runtime */ lua_State *L = NULL; #endif /* master file descriptor list */ fd_set used_fds, serv_fds, read_fds; /* working structs */ struct addrinfo hints; struct http_request *req; struct path_info *pin; struct client *cl; struct sigaction sa; struct config conf; /* signal mask */ sigset_t ss; /* maximum file descriptor number */ int new_fd, cur_fd, max_fd = 0; int tls = 0; int keys = 0; int bound = 0; int nofork = 0; /* args */ int opt; char bind[128]; char *port = NULL; /* library handles */ void *tls_lib; void *lua_lib; /* clear the master and temp sets */ FD_ZERO(&used_fds); FD_ZERO(&serv_fds); FD_ZERO(&read_fds); /* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */ sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); sa.sa_handler = uh_sigchld; sigaction(SIGCHLD, &sa, NULL); sa.sa_handler = uh_sigterm; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); /* defer SIGCHLD */ sigemptyset(&ss); sigaddset(&ss, SIGCHLD); sigprocmask(SIG_BLOCK, &ss, NULL); /* prepare addrinfo hints */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; /* parse args */ memset(&conf, 0, sizeof(conf)); memset(bind, 0, sizeof(bind)); #ifdef HAVE_TLS /* load TLS plugin */ if( ! (tls_lib = dlopen("uhttpd_tls.so", RTLD_LAZY | RTLD_GLOBAL)) ) { fprintf(stderr, "Notice: Unable to load TLS plugin - disabling SSL support! " "(Reason: %s)\n", dlerror() ); } else { /* resolve functions */ if( !(conf.tls_init = dlsym(tls_lib, "uh_tls_ctx_init")) || !(conf.tls_cert = dlsym(tls_lib, "uh_tls_ctx_cert")) || !(conf.tls_key = dlsym(tls_lib, "uh_tls_ctx_key")) || !(conf.tls_free = dlsym(tls_lib, "uh_tls_ctx_free")) || !(conf.tls_accept = dlsym(tls_lib, "uh_tls_client_accept")) || !(conf.tls_close = dlsym(tls_lib, "uh_tls_client_close")) || !(conf.tls_recv = dlsym(tls_lib, "uh_tls_client_recv")) || !(conf.tls_send = dlsym(tls_lib, "uh_tls_client_send")) ) { fprintf(stderr, "Error: Failed to lookup required symbols " "in TLS plugin: %s\n", dlerror() ); exit(1); } /* init SSL context */ if( ! (conf.tls = conf.tls_init()) ) { fprintf(stderr, "Error: Failed to initalize SSL context\n"); exit(1); } } #endif while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:t:")) > 0 ) { switch(opt) { /* [addr:]port */ case 'p': case 's': if( (port = strrchr(optarg, ':')) != NULL ) { if( (optarg[0] == '[') && (port > optarg) && (port[-1] == ']') ) memcpy(bind, optarg + 1, min(sizeof(bind), (int)(port - optarg) - 2)); else memcpy(bind, optarg, min(sizeof(bind), (int)(port - optarg))); port++; } else { port = optarg; } #ifdef HAVE_TLS if( opt == 's' ) { if( !conf.tls ) { fprintf(stderr, "Notice: TLS support is disabled, " "ignoring '-s %s'\n", optarg ); continue; } tls = 1; } #endif /* bind sockets */ bound += uh_socket_bind( &serv_fds, &max_fd, bind[0] ? bind : NULL, port, &hints, (opt == 's'), &conf ); break; #ifdef HAVE_TLS /* certificate */ case 'C': if( conf.tls ) { if( conf.tls_cert(conf.tls, optarg) < 1 ) { fprintf(stderr, "Error: Invalid certificate file given\n"); exit(1); } keys++; } break; /* key */ case 'K': if( conf.tls ) { if( conf.tls_key(conf.tls, optarg) < 1 ) { fprintf(stderr, "Error: Invalid private key file given\n"); exit(1); } keys++; } break; #endif /* docroot */ case 'h': if( ! realpath(optarg, conf.docroot) ) { fprintf(stderr, "Error: Invalid directory %s: %s\n", optarg, strerror(errno)); exit(1); } break; #ifdef HAVE_CGI /* cgi prefix */ case 'x': conf.cgi_prefix = optarg; break; #endif #ifdef HAVE_LUA /* lua prefix */ case 'l': conf.lua_prefix = optarg; break; /* lua handler */ case 'L': conf.lua_handler = optarg; break; #endif #if defined(HAVE_CGI) || defined(HAVE_LUA) /* script timeout */ case 't': conf.script_timeout = atoi(optarg); break; #endif /* no fork */ case 'f': nofork = 1; break; /* urldecode */ case 'd': if( (port = malloc(strlen(optarg)+1)) != NULL ) { memset(port, 0, strlen(optarg)+1); uh_urldecode(port, strlen(optarg), optarg, strlen(optarg)); printf("%s", port); free(port); exit(0); } break; /* basic auth realm */ case 'r': conf.realm = optarg; break; /* md5 crypt */ case 'm': printf("%s\n", crypt(optarg, "$1$")); exit(0); break; /* config file */ case 'c': conf.file = optarg; break; default: fprintf(stderr, "Usage: %s -p [addr:]port [-h docroot]\n" " -f Do not fork to background\n" " -c file Configuration file, default is '/etc/httpd.conf'\n" " -p [addr:]port Bind to specified address and port, multiple allowed\n" #ifdef HAVE_TLS " -s [addr:]port Like -p but provide HTTPS on this port\n" " -C file ASN.1 server certificate file\n" " -K file ASN.1 server private key file\n" #endif " -h directory Specify the document root, default is '.'\n" #ifdef HAVE_LUA " -l string URL prefix for Lua handler, default is '/lua'\n" " -L file Lua handler script, omit to disable Lua\n" #endif #ifdef HAVE_CGI " -x string URL prefix for CGI handler, default is '/cgi-bin'\n" #endif #if defined(HAVE_CGI) || defined(HAVE_LUA) " -t seconds CGI and Lua script timeout in seconds, default is 60\n" #endif " -d string URL decode given string\n" " -r string Specify basic auth realm\n" " -m string MD5 crypt given string\n" "\n", argv[0] ); exit(1); } } #ifdef HAVE_TLS if( (tls == 1) && (keys < 2) ) { fprintf(stderr, "Error: Missing private key or certificate file\n"); exit(1); } #endif if( bound < 1 ) { fprintf(stderr, "Error: No sockets bound, unable to continue\n"); exit(1); } /* default docroot */ if( !conf.docroot[0] && !realpath(".", conf.docroot) ) { fprintf(stderr, "Error: Can not determine default document root: %s\n", strerror(errno)); exit(1); } /* default realm */ if( ! conf.realm ) conf.realm = "Protected Area"; /* config file */ uh_config_parse(conf.file); #if defined(HAVE_CGI) || defined(HAVE_LUA) /* default script timeout */ if( conf.script_timeout <= 0 ) conf.script_timeout = 60; #endif #ifdef HAVE_CGI /* default cgi prefix */ if( ! conf.cgi_prefix ) conf.cgi_prefix = "/cgi-bin"; #endif #ifdef HAVE_LUA /* load Lua plugin */ if( ! (lua_lib = dlopen("uhttpd_lua.so", RTLD_LAZY | RTLD_GLOBAL)) ) { fprintf(stderr, "Notice: Unable to load Lua plugin - disabling Lua support! " "(Reason: %s)\n", dlerror() ); } else { /* resolve functions */ if( !(conf.lua_init = dlsym(lua_lib, "uh_lua_init")) || !(conf.lua_close = dlsym(lua_lib, "uh_lua_close")) || !(conf.lua_request = dlsym(lua_lib, "uh_lua_request")) ) { fprintf(stderr, "Error: Failed to lookup required symbols " "in Lua plugin: %s\n", dlerror() ); exit(1); } /* init Lua runtime if handler is specified */ if( conf.lua_handler ) { /* default lua prefix */ if( ! conf.lua_prefix ) conf.lua_prefix = "/lua"; L = conf.lua_init(conf.lua_handler); } } #endif /* fork (if not disabled) */ if( ! nofork ) { switch( fork() ) { case -1: perror("fork()"); exit(1); case 0: /* daemon setup */ if( chdir("/") ) perror("chdir()"); if( (cur_fd = open("/dev/null", O_WRONLY)) > -1 ) dup2(cur_fd, 0); if( (cur_fd = open("/dev/null", O_RDONLY)) > -1 ) dup2(cur_fd, 1); if( (cur_fd = open("/dev/null", O_RDONLY)) > -1 ) dup2(cur_fd, 2); break; default: exit(0); } } /* backup server descriptor set */ used_fds = serv_fds; /* loop */ while(run) { /* create a working copy of the used fd set */ read_fds = used_fds; /* sleep until socket activity */ if( select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1 ) { perror("select()"); exit(1); } /* run through the existing connections looking for data to be read */ for( cur_fd = 0; cur_fd <= max_fd; cur_fd++ ) { /* is a socket managed by us */ if( FD_ISSET(cur_fd, &read_fds) ) { /* is one of our listen sockets */ if( FD_ISSET(cur_fd, &serv_fds) ) { /* handle new connections */ if( (new_fd = accept(cur_fd, NULL, 0)) != -1 ) { /* add to global client list */ if( (cl = uh_client_add(new_fd, uh_listener_lookup(cur_fd))) != NULL ) { #ifdef HAVE_TLS /* setup client tls context */ if( conf.tls ) conf.tls_accept(cl); #endif /* add client socket to global fdset */ FD_SET(new_fd, &used_fds); fd_cloexec(new_fd); max_fd = max(max_fd, new_fd); } /* insufficient resources */ else { fprintf(stderr, "uh_client_add(): Can not manage more than " "%i client sockets, connection dropped\n", UH_LIMIT_CLIENTS ); close(new_fd); } } } /* is a client socket */ else { if( ! (cl = uh_client_lookup(cur_fd)) ) { /* this should not happen! */ fprintf(stderr, "uh_client_lookup(): No entry for fd %i!\n", cur_fd); goto cleanup; } /* parse message header */ if( (req = uh_http_header_recv(cl)) != NULL ) { #ifdef HAVE_LUA /* Lua request? */ if( L && uh_path_match(conf.lua_prefix, req->url) ) { conf.lua_request(cl, req, L); } else #endif /* dispatch request */ if( (pin = uh_path_lookup(cl, req->url)) != NULL ) { /* auth ok? */ if( uh_auth_check(cl, req, pin) ) { #ifdef HAVE_CGI if( uh_path_match(conf.cgi_prefix, pin->name) ) { uh_cgi_request(cl, req, pin); } else #endif { uh_file_request(cl, req, pin); } } } /* 404 */ else { uh_http_sendhf(cl, 404, "Not Found", "No such file or directory"); } } /* 400 */ else { uh_http_sendhf(cl, 400, "Bad Request", "Malformed request received"); } #ifdef HAVE_TLS /* free client tls context */ if( conf.tls ) conf.tls_close(cl); #endif cleanup: /* close client socket */ close(cur_fd); FD_CLR(cur_fd, &used_fds); /* remove from global client list */ uh_client_remove(cur_fd); } } } } #ifdef HAVE_LUA /* destroy the Lua state */ if( L != NULL ) conf.lua_close(L); #endif return 0; }
void main( int argc, char* argv[] ) { int i, ready, sock1, sock2, length; /* This receiver process will receive connection requests on these two sockets */ int msgsock ; fd_set fdin; struct timeval TO ; struct sockaddr_in server, server2; /* CREATE FIRST SOCKET */ sock1 = socket(AF_INET, SOCK_STREAM,0); if ( sock1 < 0 ) { perror("Problem in creating the first socket"); exit(0); } server.sin_addr.s_addr = INADDR_ANY ; server.sin_port = 0 ; if ( bind(sock1,(struct sockaddr *)&server, sizeof(server))) { /* Bind socket to a port */ perror ( "Binding stream socket"); exit(0); } length = sizeof(server); if ( getsockname(sock1,(struct sockaddr *)&server, &length)) { /* get the port number assigned to this socket */ perror("Getting socket's port number"); exit(0); } fprintf(stderr, "Socket 1 is connected to port%5d\n\n", ntohs(server.sin_port)); /* CREATE SECOND SOCKET */ sock2 = socket(AF_INET, SOCK_STREAM, 0); if ( sock2 < 0 ) { perror("problem in creating the second socket"); exit(0); } server2.sin_addr.s_addr = INADDR_ANY; server2.sin_port = 0 ; if ( bind(sock2, (struct sockaddr * )&server2,sizeof(server2))){ /* bind second socket to a port */ perror("Binding stream socket"); exit(0); } length = sizeof(server2); if ( getsockname(sock2,(struct sockaddr *)&server2,&length)){ /* get the port number for socket2 */ perror("getting socket's port number"); exit(0); } fprintf(stderr,"Socket 2 is connected to port %5d\n", ntohs(server2.sin_port)); /* Initialize socket fo receiving messages. */ /* ready to accept connection to sock1, up to 3 requests can be kept buffered */ listen(sock1,3); listen(sock2,3); /* Continuously wait for receiving messages on either of the two sockets. */ while (1) { FD_ZERO( &fdin ); FD_SET( sock1, &fdin); FD_SET( sock2, &fdin); TO.tv_sec = 10 ; TO.tv_usec = 0 ; select(32, (fd_set *)&fdin, 0, 0, &TO); /* Block to receive call on either sock1 or sock2 */ /* timeout and continue after 10 seconds if no connection requests */ if (FD_ISSET(sock1, &fdin )) { /* check if connection requests for sock1 */ printf("\nMessage on the first socket\n"); /* accept connection on sock1. This will return a new socket indentifier, stored in msgsock for the connection. All I/O for that connection is through msgsock. */ handle_connection(sock1); FD_CLR(sock1, &fdin); } else if (FD_ISSET(sock2, &fdin)) { /* check if connection requests for sock2 */ printf("\nMessage on the second socket\n"); /* accept connection on sock2. This will return a new socket indentifier, stored in msgsock for the connection. All I/O for that connection is through msgsock. */ handle_connection(sock2); FD_CLR(sock2, &fdin); } else /* Select call completed due to timeout and there is no connection on any socket */ printf("\nTimeout occured\n"); }; }
/** * DTLS over SCTP specific listener function. This function is called by @c listenerThread() */ void IpfixReceiverDtlsSctpIpV4::run() { struct sockaddr_in clientAddress; socklen_t clientAddressLen = sizeof(struct sockaddr_in); int ret; int rfd; struct timespec timeOut; /* set a 400ms time-out on the pselect */ timeOut.tv_sec = 0L; timeOut.tv_nsec = 400000000L; while(!exitFlag) { fd_set tmpreadfds = readfds; fd_set tmpwritefds = writefds; ret = pselect(maxfd + 1, &tmpreadfds, &tmpwritefds, NULL, &timeOut, NULL); if (ret == 0) { /* Timeout */ continue; } if ((ret == -1) && (errno == EINTR)) { DPRINTF("select() returned due to signal"); /* There was a signal... ignore */ continue; } if (ret < 0) { msg(MSG_ERROR ,"select() returned with an error: %s",strerror(errno)); THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: terminating listener thread"); break; } DPRINTF("select() returned %d",ret); // looking for a new client to connect at listen_socket if (FD_ISSET(listen_socket, &tmpreadfds)){ rfd = accept(listen_socket, (struct sockaddr*)&clientAddress, &clientAddressLen); if (rfd >= 0){ if ( ! isHostAuthorized(&clientAddress.sin_addr, sizeof(clientAddress.sin_addr))) { /* Do not accept connections from unauthorized hosts. */ close(rfd); } else { msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Client connected from %s:%d, FD=%d", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port), rfd); DtlsConnectionPtr conn = DtlsConnectionPtr( new DtlsConnection(*this,&clientAddress,rfd)); connections.insert(make_pair(rfd,conn)); update_maxfd(); } }else{ msg(MSG_ERROR ,"accept() in ipfixReceiver failed"); /* TODO: Don't throw an exception here. */ THROWEXCEPTION("IpfixReceiverDtlsSctpIpV4: unable to accept new connection"); } } // check all connected sockets for new available data for (rfd = 0; rfd <= maxfd; ++rfd) { if (rfd == listen_socket) continue; if (FD_ISSET(rfd, &readfds) || FD_ISSET(rfd, &writefds)) { if (FD_ISSET(rfd, &readfds)) DPRINTF("descriptor %d is ready for reading",rfd); if (FD_ISSET(rfd, &writefds)) DPRINTF("descriptor %d is ready for writing",rfd); connections_map::iterator it = connections.find(rfd); if (it == connections.end()) { /* This should not happend. */ msg(MSG_ERROR,"Can't find connection for file descriptor."); FD_CLR(rfd,&readfds); FD_CLR(rfd,&writefds); continue; } ret = it->second->fdready(); if (ret == 0) { DPRINTF("fdready() returned 0. Deleting connection."); remove_connection(rfd); update_maxfd(); } } } } msg(MSG_DEBUG, "IpfixReceiverDtlsSctpIpV4: Exiting"); }
int main(int argc, char const *argv[]) { int listendfd, connfd; int maxfd; int clilent[FD_SETSIZE]; fd_set rset, allset; pid_t childid; socklen_t clilen; struct sockaddr_in servaddr, cliaddr; char buff[MAXLINE + 1] = {0}; time_t ticks; listendfd = Socket(AF_INET, SOCK_STREAM,0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); bind(listendfd, (struct sockaddr*)&servaddr, sizeof(servaddr)); listen(listendfd, LISTENQ); signal(SIGCHLD, sig_chld); maxfd = listendfd; for(;;) { rset = allset; nready = select(maxfd + 1, &rset, NULL,NULL,NULL); if(FD_ISSET(listendfd)) { clilen = sizeof(cliaddr); connfd = accept(listendfd, (struct sockaddr*)&cliaddr,&clilen); if(connfd < 0) { if(errno == EINTR) { continue; } else { perror("accept"); } } for(i = 0; i< FD_SETSIZE; ++i) { if(clilent[i] < 0) clilent[i] = connfd; break; } if(i == FD_SETSIZE) { printf("too many clients\n"); } FD_SET(connfd, &allset); if(connfd > maxfd) maxfd = connfd; if(i > maxi) maxi = i; if(--nready < 0) continue; } for(i = 0; i < maxfd; ++i) { if( (sockfd = clilent[i]) < 0) continue; if(FD_ISSET(sockfd, &rset)) { if( (n = read(sockfd, buff, MAXLINE)) == 0) { close(sockfd); FD_CLR(sockfd, &allset); clilent[i] = -1; } else { write(sockfd, buff, n); } if(--nready <= 0) { break; } } } } return 0; }
int main(int argc,char **argv) { int i,srv_sock,j,retval,ptype; struct sockaddr_in srv_sa; int clientfds[MAX_CLIENTS]; char *clientsas[MAX_CLIENTS]; int client_cnt = 0; int block_size = 1024; int maxfd = 0; int c; char *srvhost = NULL; short srvport = DEF_SRV_PORT; int proto = DEF_PROTO; int debug = 0; char *buf = NULL; fd_set rfds; fd_set static_rfds; /* grab some quick args, hostname, port, tcp, udp... */ while ((c = getopt(argc,argv,"h:p:tudb:")) != -1) { switch(c) { case 'h': srvhost = optarg; break; case 'p': srvport = atoi(optarg); break; case 't': proto = SOCK_STREAM; break; case 'u': proto = SOCK_DGRAM; fatal("no udp support yet!"); break; case 'd': ++debug; break; case 'b': block_size = atoi(optarg); break; default: break; } } if ((buf = (char *)malloc(sizeof(char)*block_size)) == NULL) { efatal("no memory for data buf"); } if ((retval = fill_sockaddr(srvhost,srvport,&srv_sa)) != 0) { if (retval == -1) { fatal("bad port"); } else { efatal("host lookup failed"); } } /* startup server... */ if ((srv_sock = socket(AF_INET,proto,0)) == -1) { efatal("could not get socket"); } if (bind(srv_sock, (struct sockaddr *)&srv_sa, sizeof(struct sockaddr_in) ) < 0) { efatal("could not bind"); } if (proto == PROTO_TCP) { if (listen(srv_sock,8) < 0) { efatal("could not listen"); } } /* daemonize... */ if (!debug) { daemon(0,0); } for (i = 0; i < MAX_CLIENTS; ++i) { clientfds[i] = -1; clientsas[i] = (char *)malloc(MAX_NAME_LEN + 1); } FD_ZERO(&static_rfds); FD_SET(srv_sock,&static_rfds); maxfd = srv_sock; /* listen and read forever */ while (1) { /* reset fdsets */ memcpy(&rfds,&static_rfds,sizeof(static_rfds)); retval = select(maxfd+1,&rfds,NULL,NULL,NULL); if (retval > 0) { if (FD_ISSET(srv_sock,&rfds)) { struct sockaddr_in client_sin; socklen_t slen; int client_fd; slen = sizeof(client_sin); if ((client_fd = accept(srv_sock, (struct sockaddr *)&client_sin, &slen)) < 0) { warn("accept failed"); } else if (client_cnt >= MAX_CLIENTS) { warn("already at max clients"); } else { /* add new client... */ for (i = 0; i < MAX_CLIENTS; ++i) { if (clientfds[i] == -1) { break; } } clientfds[i] = client_fd; if (client_fd > maxfd) { maxfd = client_fd; } FD_SET(client_fd,&static_rfds); if (debug) { fprintf(stdout, "connect from %s:%d\n", inet_ntoa(client_sin.sin_addr), ntohs(client_sin.sin_port)); } char *addr = inet_ntoa(client_sin.sin_addr); int addrlen = strlen(addr); strncpy(clientsas[i], addr, (addrlen > MAX_NAME_LEN)?MAX_NAME_LEN:addrlen); /* null term if strncpy couldn't */ if (addrlen > MAX_NAME_LEN) { clientsas[i][MAX_NAME_LEN] = '\0'; } ++client_cnt; } } else { for (i = 0; i < MAX_CLIENTS; ++i) { if (clientfds[i] > -1) { if (FD_ISSET(clientfds[i],&rfds)) { /* read a block, or as much as possible */ retval = read(clientfds[i],buf,block_size); /* dead client, pretty much */ if (retval <= 0) { if (debug) { fprintf(stdout, "disconnect from %s\n", clientsas[i]); } close(clientfds[i]); FD_CLR(clientfds[i],&static_rfds); clientfds[i] = -1; --client_cnt; } else if (debug > 2 ) { fprintf(stdout, "DEBUG: read %d bytes from %s\n", retval, clientsas[i]); } } } } } } else if (retval < 0) { /* error... */ ewarn("error in select"); } } return -1; }
void relay_udp(SOCKS_STATE *state) { fd_set rfds; int nfds, sfd; struct timeval tv; struct timezone tz; ssize_t wc; rlyinfo ri; int done; u_long max_count = idle_timeout; u_long timeout_count; struct sockaddr_storage ss; LOGINFO li; memset(&ri, 0, sizeof(ri)); memset(&li, 0, sizeof(li)); ri.ss = (struct sockaddr *)&ss; ri.flags = 0; ri.nr = BUFSIZE-sizeof(UDPH); setsignal(SIGALRM, timeout); gettimeofday(&li.start, &tz); li.bc = li.upl = li.dnl = 0; timeout_count = 0; for (;;) { FD_ZERO(&rfds); FD_SET(state->s, &rfds); FD_SET(state->sr.udp->d, &rfds); nfds = MAX(state->s, state->sr.udp->d); if (state->r >= 0) { FD_SET(state->r, &rfds); nfds = MAX(nfds, state->r); } if (state->sr.udp->u >= 0) { FD_SET(state->sr.udp->u, &rfds); nfds = MAX(nfds, state->sr.udp->u); } done = 0; /* idle timeout related setting. */ tv.tv_sec = 60; tv.tv_usec = 0; /* unit = 1 minute. */ tz.tz_minuteswest = 0; tz.tz_dsttime = 0; sfd = select(nfds+1, &rfds, 0, 0, &tv); if (sfd > 0) { /* UDP channels */ /* in case of UDP, wc == 0 does not mean EOF (??) */ if (FD_ISSET(state->sr.udp->d, &rfds)) { ri.from = state->sr.udp->d; ri.to = state->sr.udp->u; ri.dir = UP; if ((wc = forward_udp(&ri, state->sr.udp, state->rtbl.rl_meth)) < 0) done++; else li.bc += wc; li.upl += wc; FD_CLR(state->sr.udp->d, &rfds); } if (state->sr.udp->u >= 0 && FD_ISSET(state->sr.udp->u, &rfds)) { ri.from = state->sr.udp->u; ri.to = state->sr.udp->d; ri.dir = DOWN; if ((wc = forward_udp(&ri, state->sr.udp, state->rtbl.rl_meth)) < 0) done++; else li.bc += wc; li.dnl += wc; FD_CLR(state->sr.udp->d, &rfds); } /* packets on TCP channel may indicate termination of UDP assoc. */ if (FD_ISSET(state->s, &rfds)) { ri.from = state->s; ri.to = state->r; ri.flags = 0; if ((wc = forward(&ri)) <= 0) done++; FD_CLR(state->s, &rfds); } if (FD_ISSET(state->r >= 0 && state->r, &rfds)) { ri.from = state->r; ri.to = state->s; ri.flags = 0; if ((wc = forward(&ri)) <= 0) done++; FD_CLR(state->r, &rfds); } if (done > 0) break; } else if (sfd < 0) { if (errno != EINTR) break; } else { /* sfd == 0 */ if (max_count != 0) { timeout_count++; if (timeout_count > max_count) break; } } } gettimeofday(&li.end, &tz); /* getsockname for logging */ state->sr.udp->si.myc.len = SS_LEN; getsockname(state->sr.udp->d, &state->sr.udp->si.myc.addr.sa, (socklen_t *)&state->sr.udp->si.myc.len); if (state->sr.udp->u >= 0) { state->sr.udp->si.mys.len = SS_LEN; getsockname(state->sr.udp->u, &state->sr.udp->si.mys.addr.sa, (socklen_t *)&state->sr.udp->si.mys.len); } log_transfer(&state->sr.udp->si, &li); close(state->s); if (state->r >= 0) close(state->r); close(state->sr.udp->d); if (state->sr.udp->u >= 0) close(state->sr.udp->u); if (state->sr.udp != NULL) free(state->sr.udp); }
void net_unregister_except(int fd) { FD_CLR(fd, &global_except_set); }