void server_task(void* arg) { struct cornet_config_t* config; struct client_config_t cconfig; int cfd, fd; char remote[16]; int rport; config = (struct cornet_config_t*)arg; if (!config->name) { config->name = "server_task"; } taskname(config->name); if ((fd = netannounce(config->istcp, config->server, config->port)) < 0) { fprintf(stderr, "cannot announce on tcp port %d: %s\n", config->port, strerror(errno)); taskexitall(1); } cconfig.h = config->h; while((cfd = netaccept(fd, remote, &rport)) >= 0){ fprintf(stderr, "connection from %s:%d\n", remote, rport); cconfig.fd = cfd; taskcreate(client_task, &cconfig, config->stack_size); } close(fd); printf("Exiting server task: %d\n", taskid()); }
/* iperf_udp_listen * * start up a listener for UDP stream connections */ int iperf_udp_listen(struct iperf_test *test) { int s; if ((s = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port)) < 0) { i_errno = IESTREAMLISTEN; return -1; } return s; }
/* * iperf_udp_listen * * Start up a listener for UDP stream connections. Unlike for TCP, * there is no listen(2) for UDP. This socket will however accept * a UDP datagram from a client (indicating the client's presence). */ int iperf_udp_listen(struct iperf_test *test) { int s; if ((s = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port)) < 0) { i_errno = IESTREAMLISTEN; return -1; } /* * The caller will put this value into test->prot_listener. */ return s; }
/* iperf_udp_accept * * accepts a new UDP connection */ int iperf_udp_accept(struct iperf_test *test) { struct sockaddr_storage sa_peer; int buf; socklen_t len; int sz, s; s = test->prot_listener; len = sizeof(sa_peer); if ((sz = recvfrom(test->prot_listener, &buf, sizeof(buf), 0, (struct sockaddr *) &sa_peer, &len)) < 0) { i_errno = IESTREAMACCEPT; return -1; } if (connect(s, (struct sockaddr *) &sa_peer, len) < 0) { i_errno = IESTREAMACCEPT; return -1; } test->prot_listener = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port); if (test->prot_listener < 0) { i_errno = IESTREAMLISTEN; return -1; } FD_SET(test->prot_listener, &test->read_set); test->max_fd = (test->max_fd < test->prot_listener) ? test->prot_listener : test->max_fd; /* Let the client know we're ready "accept" another UDP "stream" */ buf = 987654321; if (write(s, &buf, sizeof(buf)) < 0) { print_trace(); i_errno = IESTREAMWRITE; return -1; } return s; }
void taskmain(int argc, char **argv) { int cfd, fd; int rport; char remote[16]; if(argc != 2){ fprintf(stderr, "usage: tcplongconnection localport \n"); taskexitall(1); } if((fd = netannounce(TCP, 0, atoi(argv[1]))) < 0){ fprintf(stderr, "cannot announce on tcp port %d: %s\n", atoi(argv[1]), strerror(errno)); taskexitall(1); } fdnoblock(fd); while((cfd = netaccept(&fd, remote, &rport)) >= 0){ fprintf(stderr, "connection from %s:%d\n", remote, rport); taskcreate(proxytask, (void*)cfd, STACK); } }
Server *load_server(const char *db_file, const char *server_uuid, Server *old_srv) { int rc = 0; Server *srv = NULL; rc = Config_init_db(db_file); check(rc == 0, "Failed to load config database at %s", db_file); rc = Config_load_settings(); check(rc != -1, "Failed to load global settings."); rc = Config_load_mimetypes(); check(rc != -1, "Failed to load mime types."); srv = Config_load_server(server_uuid); check(srv, "Failed to load server %s from %s", server_uuid, db_file); check(srv->default_host, "No default_host set for server: %s, you need one host named: %s", server_uuid, bdata(srv->default_hostname)); if(old_srv == NULL || old_srv->listen_fd == -1) { srv->listen_fd = netannounce(TCP, bdata(srv->bind_addr), srv->port); check(srv->listen_fd >= 0, "Can't announce on TCP port %d", srv->port); check(fdnoblock(srv->listen_fd) == 0, "Failed to set listening port %d nonblocking.", srv->port); } else { srv->listen_fd = old_srv->listen_fd; } check(Server_start_handlers(srv, old_srv) == 0, "Failed to start handlers."); Config_close_db(); return srv; error: Server_destroy(srv); Config_close_db(); return NULL; }
/* * iperf_udp_accept * * Accepts a new UDP "connection" */ int iperf_udp_accept(struct iperf_test *test) { struct sockaddr_storage sa_peer; int buf; socklen_t len; int sz, s; /* * Get the current outstanding socket. This socket will be used to handle * data transfers and a new "listening" socket will be created. */ s = test->prot_listener; /* * Grab the UDP packet sent by the client. From that we can extract the * client's address, and then use that information to bind the remote side * of the socket to the client. */ len = sizeof(sa_peer); if ((sz = recvfrom(test->prot_listener, &buf, sizeof(buf), 0, (struct sockaddr *) &sa_peer, &len)) < 0) { i_errno = IESTREAMACCEPT; return -1; } if (connect(s, (struct sockaddr *) &sa_peer, len) < 0) { i_errno = IESTREAMACCEPT; return -1; } /* * Set socket buffer size if requested. Do this for both sending and * receiving so that we can cover both normal and --reverse operation. */ int opt; if ((opt = test->settings->socket_bufsize)) { if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) < 0) { i_errno = IESETBUF; return -1; } if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) < 0) { i_errno = IESETBUF; return -1; } } /* * Create a new "listening" socket to replace the one we were using before. */ test->prot_listener = netannounce(test->settings->domain, Pudp, test->bind_address, test->server_port); if (test->prot_listener < 0) { i_errno = IESTREAMLISTEN; return -1; } FD_SET(test->prot_listener, &test->read_set); test->max_fd = (test->max_fd < test->prot_listener) ? test->prot_listener : test->max_fd; /* Let the client know we're ready "accept" another UDP "stream" */ buf = 987654321; /* any content will work here */ if (write(s, &buf, sizeof(buf)) < 0) { i_errno = IESTREAMWRITE; return -1; } return s; }