void main() { int iterations = 0, i = 0, j = 0; char path[] = {"/home/eduard/workspace/"}; client_node *cli_nod = NULL; client *cli = NULL; process_node *proc_nod = NULL, *temp_node = NULL, *temp_node_two = NULL; process *proc = NULL; //printf("two \n"); while(iterations < 10000){ clients = new_client_list(NULL ,path); for (j = 0; j < 10; j++){ cli = new_client((uv_tcp_t *) malloc(sizeof(uv_tcp_t)), new_process_node(new_null_process(), NULL)); for(i = 0; i < 500; i++){ //printf ("%d \n", i); proc = new_null_process(); cli->processes = new_process_node(proc, cli->processes); if (i % 100 == 110) printf("i = %d ", i); } //printf(" \n"); clients->head = new_client_node(cli, clients->head); //printf("j = %d ", j); } //printf(" \n"); //printf("client node ptr "); clients = free_client_list(clients); //printf("one \n"); if (++iterations % 1000 == 0) printf("looped %d times\n", iterations); } }
VhostClient* new_vhost_client(const char* path) { VhostClient* vhost_client = (VhostClient*) calloc(1, sizeof(VhostClient)); int idx = 0; //TODO: handle errors here vhost_client->client = new_client(path); vhost_client->page_size = VHOST_CLIENT_PAGE_SIZE; // Create and attach shm to memory regions vhost_client->memory.nregions = VHOST_CLIENT_VRING_NUM; for (idx = 0; idx < vhost_client->memory.nregions; idx++) { void* shm = init_shm(VHOST_SOCK_NAME, vhost_client->page_size, idx); if (!shm) { fprintf(stderr, "Creatig shm %d failed\n", idx); free(vhost_client->client); free(vhost_client); return 0; } vhost_client->memory.regions[idx].guest_phys_addr = (uintptr_t) shm; vhost_client->memory.regions[idx].memory_size = vhost_client->page_size; vhost_client->memory.regions[idx].userspace_addr = (uintptr_t) shm; } // init vrings on the shm (through memory regions) if (vring_table_from_memory_region(vhost_client->vring_table_shm, VHOST_CLIENT_VRING_NUM, &vhost_client->memory) != 0) { // TODO: handle error here } return vhost_client; }
void check_new_client(void) { int clientfd = accept(server_socket, NULL, NULL); if (clientfd >= 0) new_client(clientfd); }
static void server(int sock) { char buff[BUF_SIZE + 1]; int actual; t_server server; actual = 0; init_server(&server, sock); while (1) { init_fds(&server, actual); if (select(server.max + 1, &server.rdfs, NULL, NULL, NULL) == -1) exit_error("select"); if (FD_ISSET(STDIN_FILENO, &server.rdfs)) break ; else if (FD_ISSET(server.sock, &server.rdfs)) { if (new_client(&server, &actual, buff) == -1) continue ; } else client_talking(&server, &actual, buff); } clear_clients(server.clients, actual); close(server.sock); }
void client_accept_cb(uv_stream_t *server, int status) { struct client_context *client = new_client(); struct remote_context *remote = new_remote(idle_timeout); client->remote = remote; remote->client = client; uv_timer_init(server->loop, remote->timer); uv_tcp_init(server->loop, &client->handle.tcp); uv_tcp_init(server->loop, &remote->handle.tcp); int rc = uv_accept(server, &client->handle.stream); if (rc == 0) { int namelen = sizeof client->addr; uv_tcp_getpeername(&client->handle.tcp, &client->addr, &namelen); reset_timer(remote); // start timer connect_to_remote(remote); } else { logger_log(LOG_ERR, "accept error: %s", uv_strerror(rc)); close_client(client); close_remote(remote); } }
typename socket_server<S,D>::client socket_server<S,D>::wait_new_client () { socklen_t sizeof_addr = sizeof(sockaddr_in); sockaddr_in addr; socket_t cli_sock = accept(sock, (sockaddr*)(&addr), &sizeof_addr); if (cli_sock == SOCKET_ERROR) throw server_accept_error(); client new_client(cli_sock, addr); return new_client; }
std::unique_ptr<Socket> Listener::accept_client() { struct sockaddr_in addr; socklen_t length = sizeof(addr); std::unique_ptr<Socket> new_client(new Socket(accept(ld, (struct sockaddr *) &addr, &length))); new_client->options = addr; return new_client; }
static void client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) { struct server_context *server = container_of(handle, struct server_context, udp); if (nread > 0) { char key[KEY_BYTES + 1] = {0}; crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0); struct client_context *client = NULL; uv_mutex_lock(&mutex); cache_lookup(cache, key, (void *)&client); uv_mutex_unlock(&mutex); if (client == NULL) { client = new_client(); client->addr = *addr; client->local_handle = handle; memcpy(client->key, key, sizeof(key)); uv_timer_init(handle->loop, client->timer); uv_udp_init(handle->loop, &client->server_handle); client->server_handle.data = client; uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb); uv_mutex_lock(&mutex); cache_insert(cache, client->key, (void *)client); uv_mutex_unlock(&mutex); } int clen = nread + PRIMITIVE_BYTES + addrlen; int mlen = nread + addrlen; uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES - addrlen; uint8_t *m = (uint8_t *)buf->base - addrlen; if (server->dest_addr->sa_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *)server->dest_addr; m[0] = 1; memcpy(m + 1, &addr->sin_addr, 4); memcpy(m + 1 + 4, &addr->sin_port, 2); } else { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)server->dest_addr; m[0] = 4; memcpy(m + 1, &addr->sin6_addr, 16); memcpy(m + 1 + 16, &addr->sin6_port, 2); } int rc = crypto_encrypt(c, m, mlen); if (!rc) { reset_timer(client); forward_to_server(server->server_addr, client, c, clen); } } else { goto error; } return; error: free(buf->base - addrlen - PRIMITIVE_BYTES); }
static int server_new_client(t_server *server, int *actual, char *buff) { if (new_client(server, actual, buff) == -1) { server->connected--; return (1); } return (0); }
/* * * SOCKS5 UDP Request * +----+------+------+----------+----------+----------+ * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT | DATA | * +----+------+------+----------+----------+----------+ * | 2 | 1 | 1 | Variable | 2 | Variable | * +----+------+------+----------+----------+----------+ * */ static void client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) { struct server_context *server = container_of(handle, struct server_context, udp); if (nread > 0) { uint8_t frag = buf->base[2]; if (frag) { logger_log(LOG_ERR, "don't support udp dgram frag"); goto err; } char key[KEY_BYTES + 1] = {0}; crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0); struct client_context *client = NULL; uv_mutex_lock(&mutex); cache_lookup(cache, key, (void *)&client); uv_mutex_unlock(&mutex); if (client == NULL) { client = new_client(); client->addr = *addr; client->local_handle = handle; memcpy(client->key, key, sizeof(key)); uv_timer_init(handle->loop, client->timer); uv_udp_init(handle->loop, &client->server_handle); client->server_handle.data = client; uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb); uv_mutex_lock(&mutex); cache_insert(cache, client->key, (void *)client); uv_mutex_unlock(&mutex); } int clen = nread - 3 + PRIMITIVE_BYTES; uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES; int rc = crypto_encrypt(c, (uint8_t*)buf->base + 3, nread - 3); if (!rc) { reset_timer(client); forward_to_server(server->server_addr, client, c, clen); } } else { goto err; } return; err: free(buf->base - PRIMITIVE_BYTES); }
static void lookup(const char *target) { dns_name_t name; unsigned char namedata[256]; client_t *client; isc_buffer_t t, namebuf; isc_result_t result; unsigned int options; INSIST(target != NULL); client = new_client(); isc_buffer_init(&t, target, strlen(target)); isc_buffer_add(&t, strlen(target)); isc_buffer_init(&namebuf, namedata, sizeof(namedata)); dns_name_init(&name, NULL); result = dns_name_fromtext(&name, &t, dns_rootname, ISC_FALSE, &namebuf); check_result(result, "dns_name_fromtext %s", target); result = dns_name_dup(&name, mctx, &client->name); check_result(result, "dns_name_dup %s", target); options = 0; options |= DNS_ADBFIND_INET; options |= DNS_ADBFIND_INET6; options |= DNS_ADBFIND_WANTEVENT; options |= DNS_ADBFIND_HINTOK; options |= DNS_ADBFIND_GLUEOK; result = dns_adb_createfind(adb, t2, lookup_callback, client, &client->name, dns_rootname, options, now, NULL, view->dstport, &client->find); #if 0 check_result(result, "dns_adb_createfind()"); #endif dns_adb_dumpfind(client->find, stderr); if ((client->find->options & DNS_ADBFIND_WANTEVENT) != 0) { client->target = target; ISC_LIST_APPEND(clients, client, link); } else { printf("NAME %s: err4 %s, err6 %s\n", target, isc_result_totext(client->find->result_v4), isc_result_totext(client->find->result_v6)); dns_adb_destroyfind(&client->find); free_client(&client); } }
/* main processing loop */ static void process(int ux_sock) { struct pollfd *polls = NULL; while (1) { struct client *c; int i, poll_count; /* setup for a poll */ polls = x_realloc(polls, (1+num_clients) * sizeof(*polls)); polls[0].fd = ux_sock; polls[0].events = POLLIN; /* setup the clients */ for (i=1, c = clients; c; i++, c = c->next) { polls[i].fd = c->fd; polls[i].events = POLLIN; } /* most of our life is spent in this call */ poll_count = poll(polls, i, SLEEP_TIME); if (poll_count == -1) { /* something went badly wrong! */ perror("poll"); exit(1); } if (poll_count == 0) { /* timeout */ timer_processing(); continue; } /* see if a client wants to speak to us */ for (i=1, c = clients; c; i++) { struct client *next = c->next; if (polls[i].revents & POLLIN) { client_input(c); } c = next; } /* see if we got a new client */ if (polls[0].revents & POLLIN) { new_client(ux_sock); } } }
int main(int argc, char** argv) { if (argc < 2) { printf("usage: libstor-c CONFIG\n"); return 1; } result c = new_client(argv[1]); if (c.err) { printf("libstor-c: error: %s\n", c.err); return 1; } h client_id = *((h*)c.val); result v = volumes(client_id, 0); if (v.err) { printf("libstor-c: error: %s\n", v.err); close(client_id); return 1; } service_volume_map svm = *((service_volume_map*)v.val); for (int x = 0; x < svm.services_c; x++) { printf("service: %s\n", svm.service_names[x]); volume_map vm = *svm.volumes[x]; for (int y = 0; y < vm.volumes_c; y++) { volume vol = *vm.volumes[y]; printf("\n"); printf(" - volume: %s\n", vm.volume_ids[y]); printf(" name: %s\n", vol.name); printf(" iops: %" PRId64 "\n", vol.iops); printf(" size: %" PRId64 "\n", vol.size); printf(" type: %s\n", vol.volume_type); printf(" zone: %s\n", vol.availability_zone); printf(" status: %s\n", vol.status); printf(" netnam: %s\n", vol.network_name); } printf("\n"); } close(client_id); return 0; }
/** * Executa o comando NICK * @param server * @param socket * @param msg * @param addr * @param port */ void run_nick(Server* server, Socket socket, char* msg, char* addr, int port){ char username[20]; char command[10]; //estrai o comando e o nome de usuario da mensagem sscanf(msg, "%s%s", command, username); Client* c = new_client(username, addr, port); Client** last; //verifica se o nome de usuario ja esta em uso for(last = &server->client_list; *last != NULL; last = &(*last)->next){ if(strcmp(username, (*last)->username) == 0){ send_message(socket, addr, port, "NICK taken\n"); free_clients(c); return; } } *last = c; send_message(socket, addr, port, "NICK success\n"); }
void connect_client(t_server *server) { int i; server->actual = 0; server->fd_max = server->fd_socket; while (1) { FD_ZERO(&server->readf); FD_SET(server->fd_socket, &server->readf); for(i = 0 ; i < server->actual ; i++) { FD_SET(clients[i].sock, &server->readf); } if (select(server->fd_max + 1, &server->readf, NULL, NULL, NULL) == -1) perror("select"); if (FD_ISSET(server->fd_socket, &server->readf)) new_client(server); do_client(server); } }
static void accept_cb(uv_stream_t *stream, int status) { struct tundev_context *ctx = stream->data; struct client_context *client = new_client(ctx->tun->mtu); uv_tcp_init(stream->loop, &client->handle.tcp); int rc = uv_accept(stream, &client->handle.stream); if (rc == 0) { int len = sizeof(struct sockaddr); uv_tcp_getpeername(&client->handle.tcp, &client->addr, &len); client->handle.stream.data = ctx; uv_tcp_nodelay(&client->handle.tcp, 1); uv_tcp_keepalive(&client->handle.tcp, 1, 60); client->packet.size = 512; ctx->connect = AUTHING; uv_read_start(&client->handle.stream, alloc_cb, recv_cb); } else { logger_log(LOG_ERR, "accept error: %s", uv_strerror(rc)); close_client(client); } }
int handle_connection(int client_socket_descriptor) { SOCKS4RequestHeader header; SOCKS4IP4RequestBody req; recv(client_socket_descriptor, (char*)&header, sizeof(SOCKS4RequestHeader), 0); if(header.version != 4 || header.cmd != CMD_CONNECT) { fprintf (stderr, "Incorrect header.\n"); return -1;} if(recv(client_socket_descriptor, (char*)&req, sizeof(SOCKS4IP4RequestBody), 0) != sizeof(SOCKS4IP4RequestBody)) { fprintf (stderr, "Error in request reception.\n"); return -1;} char c=' '; while(c!='\0') { if(recv(client_socket_descriptor, &c, 1, 0) != 1) { fprintf (stderr, "Error in username reception.\n"); return -1;} } if (new_client (client_socket_descriptor, ntohl(req.ip_dst), ntohs(req.port)) == -1) { fprintf (stderr, "Failed to connect to target.\n"); return -1; } return 0; }
int main(void) { memset(clients, 0, sizeof(Client) * MAXCLIENTS); signal(SIGCHLD, SIG_IGN); //signal(SIGPIPE, ) // FIXME struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP. "| AI_ADDRCONFIG" hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version hints.ai_family = AF_INET6; // IPv4 addresses will be like ::ffff:127.0.0.1 struct addrinfo *servinfo; getaddrinfo(NULL, PORT, &hints, &servinfo); #if DEBUG for(struct addrinfo *p = servinfo; p != NULL; p = p->ai_next) { char ipstr[INET6_ADDRSTRLEN]; inet_ntop(p->ai_family, get_in_addr(p->ai_addr), ipstr, sizeof(ipstr)); // convert the IP to a string printf(" %s\n", ipstr); } #endif struct addrinfo *servinfo2 = servinfo; //servinfo->ai_next; char ipstr[INET6_ADDRSTRLEN]; inet_ntop(servinfo2->ai_family, get_in_addr(servinfo2->ai_addr), ipstr, sizeof(ipstr)); printf("Waiting for connections on [%s]:%s\n", ipstr, PORT); int sockfd = socket(servinfo2->ai_family, servinfo2->ai_socktype, servinfo2->ai_protocol); #if 1 int yes_1 = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes_1, sizeof(yes_1)); #endif bind(sockfd, servinfo2->ai_addr, servinfo2->ai_addrlen); freeaddrinfo(servinfo); // all done with this structure setnonblocking(sockfd); listen(sockfd, 10); int efd = epoll_create1(0); struct epoll_event event; event.events = EPOLLIN; event.data.fd = sockfd; epoll_ctl(efd, EPOLL_CTL_ADD, sockfd, &event); struct epoll_event events[MAXEVENTS]; for(;;) { int nfd = epoll_wait(efd, events, MAXEVENTS, -1); for(int n = 0; n < nfd; ++n) { if(events[n].data.fd == sockfd) // listener { int idx = new_client(); struct sockaddr_storage their_addr; // connector's address information socklen_t addr_size = sizeof(their_addr); clients[idx].socket = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size); setnonblocking(clients[idx].socket); // maybe try accept4(2) char ipstr[INET6_ADDRSTRLEN]; inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), ipstr, sizeof(ipstr)); printf("Got a connection from %s [%d]\n", ipstr, clients[idx].socket); const char hello_msg[] = "<rembash2>\n"; send(clients[idx].socket, hello_msg, sizeof(hello_msg) - 1, 0); struct itimerspec new_value; struct timespec now; clock_gettime(CLOCK_REALTIME, &now); new_value.it_value.tv_sec = now.tv_sec + 10; new_value.it_value.tv_nsec = now.tv_nsec; new_value.it_interval.tv_sec = 0; new_value.it_interval.tv_nsec = 0; clients[idx].timer = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC); timerfd_settime(clients[idx].timer, TFD_TIMER_ABSTIME, &new_value, NULL); EventData ed; ed.fd = clients[idx].socket; ed.idx = idx; EventUnion eu; eu.d = ed; event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET; event.data.u64 = eu.u64; epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event); ed.fd = clients[idx].timer; eu.d = ed; event.events = EPOLLIN | EPOLLET; event.data.u64 = eu.u64; epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event); } else // client socket or pty or timer { char buf[BUFFERSIZE]; EventUnion eu; eu.u64 = events[n].data.u64; if(!clients[eu.d.idx].isvalid) { printf("Something bad happend on file [%d] for client [%d]\n", eu.d.fd, eu.d.idx); continue; } if (eu.d.fd == clients[eu.d.idx].timer) { printf("Time out for [%d]\n", eu.d.idx); if(clients[eu.d.idx].state == 0) { const char timer_msg[] = "TIMEOUT !\n"; send(clients[eu.d.idx].socket, timer_msg, sizeof(timer_msg) - 1, 0); printf("Client [%d] disconnected.\n", eu.d.idx); close(clients[eu.d.idx].socket); clients[eu.d.idx].isvalid = 0; } continue; } if(clients[eu.d.idx].state == 0) { // assert(eu.d.fd == clients[eu.d.idx].socket) int nbytes = recv(eu.d.fd, buf, 255, 0); // it's not 100% guaranteed to work! must use readline. if(nbytes < 1) { printf("Client [%d] disconnected.\n", eu.d.idx); close(eu.d.fd); clients[eu.d.idx].isvalid = 0; continue; } buf[nbytes - 1] = '\0'; printf("Received %s from [%d]\n", buf, eu.d.fd); if(strcmp(buf, SECRET) != 0) { const char secret_msg[] = "WRONG SECRET KEY !\n"; send(eu.d.fd, secret_msg, sizeof(secret_msg) - 1, 0); printf("Shared key check failed for [%d]\n", eu.d.idx); printf("Client [%d] disconnected.\n", eu.d.idx); close(eu.d.fd); clients[eu.d.idx].isvalid = 0; continue; } const char ok_msg[] = "<ok>\n"; send(eu.d.fd, ok_msg, sizeof(ok_msg) - 1, 0); clients[eu.d.idx].state = 1; clients[eu.d.idx].pid = forkpty(&clients[eu.d.idx].pty, NULL, NULL, NULL); if(clients[eu.d.idx].pid == 0) // child { close(sockfd); // child doesn't need the listener close(efd); // child doesn't need epoll setsid(); execl("/bin/bash", "bash", NULL); _exit(0); return 0; } else { EventData ed; ed.fd = clients[eu.d.idx].pty; ed.idx = eu.d.idx; EventUnion eu; eu.d = ed; event.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET; event.data.u64 = eu.u64; epoll_ctl(efd, EPOLL_CTL_ADD, ed.fd, &event); const char ready_msg[] = "<ready>\n"; send(clients[eu.d.idx].socket, ready_msg, sizeof(ready_msg) - 1, 0); } } // if(client->state == 0) else // if(client->state == 1) { // FIXME: EPOLLHUP or EPOLLRDHUP ?!! if((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP)) { printf("Client [%d] disconnected.\n", eu.d.idx); close(clients[eu.d.idx].socket); close(clients[eu.d.idx].pty); kill(clients[eu.d.idx].pid, SIGTERM); clients[eu.d.idx].isvalid = 0; continue; } else if(events[i].events & EPOLLIN) { int bytes_available = 0; ioctl(eu.d.fd, FIONREAD, &bytes_available); exchange_data(eu.d.fd, eu.d.idx); } else if(events[i].events & EPOLLOUT) { exchange_data(eu.d.fd == clients[eu.d.idx].socket ? clients[eu.d.idx].pty : clients[eu.d.idx].socket, eu.d.idx); } else { printf("Client [%d] ???.\n", eu.d.idx); } } } // if(events[n].data.fd == sockfd) } // for(int n = 0; n < nfd; ++n) } // for(;;) return 0; }
int main(int argc, char * argv[]) { fd_set all_fds; fd_set read_fds; int nfds; /* The highest-numbered file descriptor in the set */ int listener; int yes = 1; int i, j, rv; struct addrinfo hints, *ai, *servIter; struct server_info *sInfo; unsigned char outBuf[1024]; unsigned char inBuf[3]; char playerBuf[1024]; unsigned char **map; int idCount = 0; char str[256]; int sd, n, player_loc; socklen_t client_len; unsigned char udpbuf[MAX_LEN]; struct sockaddr_in udpserver, udpclient; struct sockaddr_in clientIP[8]; u_long lttl; if(argc != 2) { printf("Usage: %s [player limit]\n", argv[0]); exit(0); } printf("------------------------------\n"); printf("Tux Bomber v1.0\n"); printf("Data Comm 0x131B\n"); printf("April 2009\n"); printf("------------------------------\n"); expectedClients = atoi(argv[1]); playerCount = expectedClients; for(i = 0; i < expectedClients; i++) player_array[i] = new DPlaya(); /* Initialize client table */ for (i = 0; i < expectedClients; i++) { memset(&clientIP[i], 0, sizeof(clientIP[i])); //clientIP[i].sin_addr.s_addr = 0; clientIP[i].sin_family = AF_INET; clientIP[i].sin_port = htons(8000); } FD_ZERO(&all_fds); FD_ZERO(&read_fds); printf("Initializing server settings..."); // initialize server settings if(!initialize_server(sInfo)) { perror("ERROR: Unable to initialize server settings!\n"); exit(1); } printf(" Success!\n"); /* Clear and set family attributes! */ 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, "server: %s\n", gai_strerror(rv)); exit(1); } printf("Creating TCP socket..."); // Set up the listening socket for (servIter = ai; servIter != NULL; servIter = servIter->ai_next) { listener = socket(servIter->ai_family, servIter->ai_socktype, servIter->ai_protocol); if (listener < 0) continue; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); /* Close the socket & continue if it's already being used, else bind it */ if (bind(listener, servIter->ai_addr, servIter->ai_addrlen) < 0) { close(listener); continue; } break; } /* Exit if bind was unsuccessful. If it was, start listening. */ if (servIter == NULL) { fprintf(stderr, "server: failed to bind\n"); exit(2); } if (listen(listener, 8) == -1) { perror("listen"); exit(3); } printf(" Success!\n"); /* Add new client to the set of all clients & make it the new nfds */ FD_SET(listener, &all_fds); nfds = listener; printf("Generating map..."); map = genRandomMap(17,18); for(int y = 0; y < 17; y++) for(int x = 0; x < 18; x++) grid[y][x] = map[y][x]; for (i = 0; i < 17; ++i) for (j = 0; j < 18; ++j) outBuf[i * 17 + j] = map[i][j]; printf(" Success!\n"); printf("Waiting for clients...\n"); /* Loop, waiting for client connections until we have all of them. */ while (idCount < expectedClients) { read_fds = all_fds; if (select(nfds + 1, &read_fds, NULL, NULL, NULL) == -1) { perror("select"); exit(4); } /* Check each connection for input */ for (i = 3; i <= nfds; i++) { if (FD_ISSET(i, &read_fds)) { if (i == listener) /* New client connection */ { nfds = new_client(nfds, listener, &all_fds, player_array[idCount], &clientIP[idCount]); printf("Client %d connected\n", idCount); if (idCount == 0) { player_array[idCount]->setX(35); player_array[idCount]->setY(35); } else if (idCount == 1) { player_array[idCount]->setX(15 * 35 - 1); player_array[idCount]->setY(15 * 35 - 1); } else if (idCount == 2) { player_array[idCount]->setX(35); player_array[idCount]->setY(15 * 35 - 1); } else if (idCount == 3) { player_array[idCount]->setX(15 * 35 - 1); player_array[idCount]->setY(35); } sprintf(str, "resources/img/models/in_game/%d.png\0", idCount); player_array[idCount]->setImageName(str); player_array[idCount]->setID(idCount); player_array[idCount]->setNumBombs(5); idCount++; break; } } } } printf("Sending out map and client information..."); for (j = 3; j <= nfds; j++) { if (FD_ISSET(j, &all_fds)) { if(j == listener) continue; if (send(j, outBuf, MAX_LEN, 0) == -1) perror("send"); } } for (j = 3; j <= nfds; j++) { if (FD_ISSET(j, &all_fds)) { if(j == listener) continue; if (send(j, argv[1], 1024, 0) == -1) perror("send"); } } /* Copy all players and send them out */ for(i = 0; i < expectedClients; i++) { memcpy(playerBuf, player_array[i], 1024); for(j = 3; j <= nfds; j++) { if(FD_ISSET(j, &all_fds)) { if(j == listener) continue; if(send(j, playerBuf, MAX_LEN, 0) == -1) perror("send"); } } } printf(" Success!\n"); printf("Creating UDP socket..."); /* Create udp listen socket */ if((sd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("Socket Creation"); exit(EXIT_FAILURE); } /* initialize sockaddr struct */ bzero((char *)&udpserver, sizeof(udpserver)); udpserver.sin_family = AF_INET; udpserver.sin_port = htons(8000); udpserver.sin_addr.s_addr = htonl(INADDR_ANY); /* bind socket to address */ if(bind(sd, (struct sockaddr *)&udpserver, sizeof(udpserver)) == -1) { perror("Binding Socket"); exit(EXIT_FAILURE); } /* create what looks like an ordinary UDP socket */ if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0) { perror("socket"); exit(1); } /* set up destination address */ memset(&addr,0,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_addr.s_addr=inet_addr(MULTI_ADDR); addr.sin_port=htons(MULTI_PORT); lttl = 10; setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)lttl, sizeof(lttl)); printf(" Success!\n"); printf("Starting game. HAVE FUN! :D\n"); /*********************** GAME STARTED HERE! ************************/ while(playerCount > 1) { memset(udpbuf, 0, sizeof(udpbuf)); memset(outBuf, 0, sizeof(outBuf)); client_len = sizeof(udpclient); /* listen for connection */ if((n = recvfrom(sd, inBuf, 3, 0, (struct sockaddr *)&udpclient, &client_len)) <= 0) { /* socket closed */ if(n == 0) { fprintf(stderr,"Connection closed on socket: %d\n", sd); continue; } else /* error */ { perror("Recv From"); exit(EXIT_FAILURE); } } if((player_loc = get_player_loc(udpclient.sin_addr.s_addr)) >= 0 && player_loc < MAX_PLAYERS) { clientIP[player_loc].sin_port = udpclient.sin_port; if(inBuf[0] - '0'== MOVE_UP) player_array[player_loc]->move(grid, MOVE_UP); else if(inBuf[0] - '0' == MOVE_DOWN) player_array[player_loc]->move(grid, MOVE_DOWN); else if(inBuf[0] - '0' == MOVE_RIGHT) player_array[player_loc]->move(grid, MOVE_RIGHT); else if(inBuf[0] - '0' == MOVE_LEFT) player_array[player_loc]->move(grid, MOVE_LEFT); else if(inBuf[0] - '0' == PLANT_BOMB) plant_bomb(player_loc); outBuf[0] = 'P'; outBuf[1] = 'P'; memcpy(outBuf + 2, player_array[player_loc], 1024); if (sendto(fd,outBuf,sizeof(outBuf),0,(struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto"); exit(1); } } } outBuf[0] = 'G'; if (sendto(fd,outBuf,sizeof(outBuf),0,(struct sockaddr *) &addr, sizeof(addr)) < 0) { perror("sendto"); exit(1); } sleep(2); shutdown(fd, 2); close(fd); printf("Game over!\n"); free(map); return 0; }
static void Iowait(void) { int maxfd; fd_set readfds; QUEUE *q; /* accept input on any descriptor */ FD_ZERO(&readfds); FD_SET(master, &readfds); maxfd = master; for (q = QFIRST(tpclients); q != &tpclients; q = QNEXT(q)) { struct tpclient * c = OFFSET(q, struct tpclient, global); if (c->fd > maxfd) maxfd = c->fd; FD_SET(c->fd, &readfds); } debug(3, "entering select to fd %d", maxfd); /* wait for something to do */ if (select(maxfd + 1, &readfds, 0, 0, 0) == -1) { error("select: %m"); return; } /* new client connection */ if (FD_ISSET(master, &readfds)) { debug(1, "new connection"); int i = accept(master, 0, 0); if (i == -1) error("accept: %m"); else svr_next_command(new_client(i)); } q = QFIRST(tpclients); while (q != &tpclients) { struct tpclient * c = OFFSET(q, struct tpclient, global); q = QNEXT(q); if (FD_ISSET(c->fd, &readfds)) { long bufsize = c->input ? tptypes(c->input, 0, 0) : 0; int used = c->used; if (used >= bufsize) // something unexpected. could be EOF { char check_eof[100]; int len = read(c->fd, &check_eof, sizeof check_eof); if (len > 0) { error("Iowait: read %d unexpected bytes from fd %d", len, c->fd); dump(c->fd, "unexpected", check_eof, len); } del_client(c); } else if ((used = read(c->fd, c->input + used, bufsize - used)) == -1) { error("Iowait: read: %m"); del_client(c); } else if (used == 0) { debug(1, "eof on %d", c->fd); del_client(c); } else if ((c->used = c->used + used) == bufsize) { void (*handle)(struct tpclient *, char *) = c->handler; char *buf = c->input; char *handler_name = c->handler_name; c->handler_name = 0; c->handler = 0; c->input = 0; c->used = 0; debug(1, "%d bytes read from %d. calling handler %s at 0x%x", bufsize, c->fd, handler_name, handle); if (DEBUG > 2) dump(c->fd, "read", buf, bufsize); handle(c, buf); debug(2, "back from handler %s at 0x%x", handler_name, handle); } else debug(2, "%d bytes read from %d. waiting for %d more...", used, c->fd, bufsize - c->used); } if (q != &tpclients) debug(2, "-------"); } }
int main(int argc, char *argv[]) { int server_port = 2121; if (argc < 2) { printf("usage: %s <addr> [2121]\n", argv[0]); exit(0); } if (argc == 3) { server_port = atoi(argv[2]); } int client = new_client(ntohl(inet_addr(argv[1])), server_port); if (client < 0) { err(1, "can not connect to %s %d", argv[1], server_port); err(1, "exit ..."); exit(1); } int i, n; char buf[BUF_SIZE+1]; char tmpbuf[BUF_SIZE+1]; char cmdbuf[BUF_SIZE+1]; int data_client = -1; struct sockaddr_in data_client_addr; uint32_t addr; uint16_t port; char path[BUF_SIZE]; int code = -1; enum CLIENT_STATE state = ST_NONE; char filename[BUF_SIZE], line[BUF_SIZE]; while ((n=recv(client, buf, sizeof(buf), MSG_PEEK)) > 0) { if (!running) break; for (i=0; i<n; i++) { if (buf[i] == '\n') break; } if (buf[i] != '\n') { err(1, "no line break found"); break; } n = recv(client, buf, i+1, 0); buf[n] = 0; printf("%s", buf); fflush(stdout); parse_number(buf, &code); if (code < RPL_ERR_UNKWNCMD && state != ST_NONE) { switch(state) { case ST_PASVLIST: case ST_PASVGET: case ST_PASVPUT: if (code == RPL_PASVOK) { strcpy(tmpbuf, buf); tmpbuf[0] = tmpbuf[1] = tmpbuf[2] = tmpbuf[3] = ' '; parse_addr_port(tmpbuf, &addr, &port); switch(state) { case ST_PASVLIST: send_str(client, "LIST\r\n"); break; case ST_PASVGET: send_str(client, "RETR %s\r\n", filename); break; case ST_PASVPUT: send_str(client, "STOR %s\r\n", filename); break; } data_client = new_client(addr, port); state++; } else { state = ST_NONE; } break; case ST_PASVLIST2: case ST_PASVGET2: case ST_PASVPUT2: if (data_client < 0) { err(1, "data client not created"); } else { if (state == ST_PASVLIST2) { recv_file(data_client, stdout); } else if (state == ST_PASVGET2) { recv_path(data_client, filename, 0); } else if (state == ST_PASVPUT2) { FILE *f = fopen(filename, "rb"); if (f) { send_file(data_client, f); fclose(f); } else { err(1, "err open file %s", filename); } } info(1, "closing data socket ... %d", close(data_client)); data_client = -1; state = ST_NONE; } break; default: state = ST_NONE; break; } if (code < RPL_ERR_UNKWNCMD) continue; } if (code >= RPL_ERR_UNKWNCMD) state = ST_NONE; int valid = 0; while (!valid) { valid = 1; printf("ftp >>> "); if (!fgets(line, BUF_SIZE, stdin)){ running = 0; break; } int len = strlen(line); len --; while (line[len] == '\n' || line[len] == '\r') len--; len ++; line[len] = 0; enum USER_CMD cmd = parse_input_cmd(line, len); switch(cmd) { case USER_USER: case USER_PASS: case USER_TYPE: case USER_MKD: case USER_DELE: case USER_RNFR: case USER_RNTO: case USER_RMD: send_str(client, "%s\r\n", line); break; case USER_LS: send_str(client, "PASV\r\n"); state = ST_PASVLIST; break; case USER_CD: send_str(client, "CWD %s\r\n", &line[3]); break; case USER_PWD: send_str(client, "PWD\r\n"); break; case USER_CDUP: send_str(client, "CDUP\r\n"); break; case USER_HELP: for (i=0; i<sizeof(USER_CMD_LIST)/sizeof(USER_CMD_LIST[0]); i++) { printf("%s\n", USER_CMD_LIST[i].name); } valid = 0; break; case USER_BYE: send_str(client, "QUIT\r\n"); running = 0; break; case USER_LCD: chdir(&line[4]); valid = 0; break; case USER_LLS: getcwd(path, sizeof(path)); printf("%s\n", path); sprintf(cmdbuf, "ls -l %s", path); FILE *p2 = popen(cmdbuf, "r"); int n; while ((n=fread(tmpbuf, 1, BUF_SIZE, p2)) > 0 ) { fwrite(tmpbuf, 1, n, stdout); } pclose(p2); valid = 0; break; case USER_LPWD: getcwd(path, sizeof(path)); printf("%s\n", path); valid = 0; break; case USER_GET: send_str(client, "PASV\r\n"); strcpy(filename, &line[4]); state = ST_PASVGET; break; case USER_PUT: send_str(client, "PASV\r\n"); strcpy(filename, &line[4]); state = ST_PASVPUT; break; default: warn(1, "unknown user cmd"); valid = 0; break; } } if (!running) break; } int st = close(client); info(1, "FTP client close socket ... %d", st); info(1, "FTP client shutdown"); if (data_client > 0) { st = close(data_client); info(1, "FTP client close data socket ... %d", st); info(1, "FTP client data socket shutdown"); } return 0; }
/* * par_main() * Endless loop to receive and serve requests */ static void par_main() { struct msg msg; int x; struct file *f; loop: /* * Receive a message, log an error and then keep going */ x = msg_receive(lp_port, &msg); if (x < 0) { syslog(LOG_ERR, "msg_receive"); goto loop; } /* * All incoming data should fit in one buffer */ if (msg.m_nseg > 1) { msg_err(msg.m_sender, EINVAL); goto loop; } /* * Categorize by basic message operation */ f = hash_lookup(filehash, msg.m_sender); switch (msg.m_op & MSG_MASK) { case M_CONNECT: /* New client */ new_client(&msg); break; case M_DISCONNECT: /* Client done */ dead_client(&msg, f); break; case M_DUP: /* File handle dup during exec() */ dup_client(&msg, f); break; case M_ABORT: /* Aborted operation */ /* * We are synchronous. At the time we handle this * message, any I/O is completed. Just answer * with an abort message. */ msg_reply(msg.m_sender, &msg); break; case FS_WRITE: /* Write */ if (check_gen(&msg, f)) { break; } par_write(&msg, f); break; case FS_STAT: /* Get stat of file */ if (check_gen(&msg, f)) { break; } par_stat(&msg, f); break; case FS_WSTAT: /* Writes stats */ if (check_gen(&msg, f)) { break; } par_wstat(&msg, f); break; default: /* Unknown */ msg_err(msg.m_sender, EINVAL); break; } goto loop; }
/* * namer_main() * Endless loop to receive and serve requests */ static void namer_main() { struct msg msg; int x; struct file *f; loop: /* * Receive a message, log an error and then keep going */ x = msg_receive(namerport, &msg); if (x < 0) { perror("namer: msg_receive"); goto loop; } /* * All requests should fit in one buffer */ if (msg.m_nseg > 1) { msg_err(msg.m_sender, EINVAL); goto loop; } /* * Categorize by basic message operation */ f = hash_lookup(filehash, msg.m_sender); switch (msg.m_op & MSG_MASK) { case M_CONNECT: /* New client */ new_client(&msg); break; case M_DISCONNECT: /* Client done */ dead_client(&msg, f); break; case M_DUP: /* File handle dup during exec() */ dup_client(&msg, f); break; case M_ABORT: /* Aborted operation */ /* * We're synchronous, so presumably the operation * is all done and this abort is old news. */ msg_reply(msg.m_sender, &msg); break; case FS_OPEN: /* Look up file from directory */ if (!valid_fname(msg.m_buf, x)) { msg_err(msg.m_sender, ESRCH); break; } namer_open(&msg, f); break; case FS_READ: /* Read file */ namer_read(&msg, f); break; case FS_WRITE: /* Write file */ namer_write(&msg, f); break; case FS_SEEK: /* Set new file position */ namer_seek(&msg, f); break; case FS_REMOVE: /* Get rid of a file */ namer_remove(&msg, f); break; case FS_STAT: /* Stat node */ namer_stat(&msg, f); break; case FS_WSTAT: /* Write stat info */ namer_wstat(&msg, f); break; default: /* Unknown */ msg_err(msg.m_sender, EINVAL); break; } goto loop; }
/* * entry point */ void * uxsock_listen(int (*uxsock_trigger)(char *, char **, int *, void *), void * trigger_data) { int ux_sock; size_t len; int rlen; char *inbuf; char *reply; ux_sock = ux_socket_listen(DEFAULT_SOCKET); if (ux_sock == -1) { condlog(0, "ux_socket_listen error"); exit(1); } pthread_cleanup_push(uxsock_cleanup, NULL); polls = (struct pollfd *)MALLOC(0); while (1) { struct client *c; int i, poll_count; /* setup for a poll */ polls = REALLOC(polls, (1+num_clients) * sizeof(*polls)); polls[0].fd = ux_sock; polls[0].events = POLLIN; /* setup the clients */ for (i=1, c = clients; c; i++, c = c->next) { polls[i].fd = c->fd; polls[i].events = POLLIN; } /* most of our life is spent in this call */ poll_count = poll(polls, i, SLEEP_TIME); if (poll_count == -1) { if (errno == EINTR) continue; /* something went badly wrong! */ condlog(0, "poll"); pthread_exit(NULL); } if (poll_count == 0) continue; /* see if a client wants to speak to us */ for (i=1, c = clients; c; i++) { struct client *next = c->next; if (polls[i].revents & POLLIN) { if (recv_packet(c->fd, &inbuf, &len) != 0) { dead_client(c); } else { inbuf[len - 1] = 0; condlog(4, "Got request [%s]", inbuf); uxsock_trigger(inbuf, &reply, &rlen, trigger_data); if (reply) { if (send_packet(c->fd, reply, rlen) != 0) { dead_client(c); } condlog(4, "Reply [%d bytes]", rlen); FREE(reply); reply = NULL; } FREE(inbuf); } } c = next; } /* see if we got a new client */ if (polls[0].revents & POLLIN) { new_client(ux_sock); } } pthread_cleanup_pop(1); close(ux_sock); return NULL; }
void xrServer::create_direct_client() { ClientID _clid; _clid.set (1); new_client (_clid, "single_player", true); }
/* * tmpfs_main() * Endless loop to receive and serve requests */ static void tmpfs_main() { struct msg msg; int x; struct file *f; extern int valid_fname(char *, int); loop: /* * Receive a message, log an error and then keep going */ x = msg_receive(rootport, &msg); if (x < 0) { syslog(LOG_ERR, "msg_receive"); goto loop; } /* * Categorize by basic message operation */ f = hash_lookup(filehash, msg.m_sender); switch (msg.m_op & MSG_MASK) { case M_CONNECT: /* New client */ new_client(&msg); break; case M_DISCONNECT: /* Client done */ dead_client(&msg, f); break; case M_DUP: /* File handle dup during exec() */ dup_client(&msg, f); break; case M_ABORT: /* Aborted operation */ /* * We're synchronous, so presumably the operation * is all done and this abort is old news. */ msg_reply(msg.m_sender, &msg); break; case FS_OPEN: /* Look up file from directory */ if ((msg.m_nseg != 1) || !valid_fname(msg.m_buf, msg.m_buflen)) { msg_err(msg.m_sender, EINVAL); break; } tmpfs_open(&msg, f); break; case FS_ABSREAD: /* Set position, then read */ if (msg.m_arg1 < 0) { msg_err(msg.m_sender, EINVAL); break; } f->f_pos = msg.m_arg1; /* VVV fall into VVV */ case FS_READ: /* Read file */ tmpfs_read(&msg, f); break; case FS_ABSWRITE: /* Set position, then write */ if (msg.m_arg1 < 0) { msg_err(msg.m_sender, EINVAL); break; } f->f_pos = msg.m_arg1; /* VVV fall into VVV */ case FS_WRITE: /* Write file */ tmpfs_write(&msg, f); break; case FS_SEEK: /* Set new file position */ tmpfs_seek(&msg, f); break; case FS_REMOVE: /* Get rid of a file */ if ((msg.m_nseg != 1) || !valid_fname(msg.m_buf, msg.m_buflen)) { msg_err(msg.m_sender, EINVAL); break; } tmpfs_remove(&msg, f); break; case FS_STAT: /* Tell about file */ tmpfs_stat(&msg, f); break; case FS_WSTAT: /* Set stuff on file */ tmpfs_wstat(&msg, f); break; case FS_FID: /* Return file ID for caching */ tmpfs_fid(&msg, f); break; default: /* Unknown */ msg_err(msg.m_sender, EINVAL); break; } goto loop; }
static void poll_cb(uv_poll_t *watcher, int status, int events) { char buffer[1024] = {0}; char control_buffer[64] = {0}; struct iovec iov[1]; struct msghdr msg; struct sockaddr client_addr; struct server_context *server = container_of(watcher, struct server_context, watcher); if (status >= 0) { msg.msg_name = &client_addr; msg.msg_namelen = sizeof(client_addr); msg.msg_control = control_buffer; msg.msg_controllen = sizeof(control_buffer); iov[0].iov_base = buffer; iov[0].iov_len = sizeof(buffer); msg.msg_iov = iov; msg.msg_iovlen = 1; int msglen = recvmsg(watcher->io_watcher.fd, &msg, 0); if (msglen <= 0) { logger_stderr("receive from client error: %s", strerror(errno)); } struct sockaddr dest_addr; if (getdestaddr(&msg, &dest_addr)) { logger_stderr("can not get destination address"); } int addrlen = dest_addr.sa_family == AF_INET ? IPV4_HEADER_LEN : IPV6_HEADER_LEN; int mlen = addrlen + msglen; int clen = PRIMITIVE_BYTES + mlen; uint8_t *c = malloc(clen); uint8_t *m = c + PRIMITIVE_BYTES; /* * * xsocks UDP Request * +------+----------+----------+----------+ * | ATYP | DST.ADDR | DST.PORT | DATA | * +------+----------+----------+----------+ * | 1 | Variable | 2 | Variable | * +------+----------+----------+----------+ * */ if (dest_addr.sa_family == AF_INET) { struct sockaddr_in *addr = (struct sockaddr_in *)&dest_addr; m[0] = ATYP_IPV4; memcpy(m + 1, &addr->sin_addr, 4); memcpy(m + 1 + 4, &addr->sin_port, 2); } else { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&dest_addr; m[0] = ATYP_IPV6; memcpy(m + 1, &addr->sin6_addr, 16); memcpy(m + 1 + 16, &addr->sin6_port, 2); } memcpy(m + addrlen, buffer, msglen); int rc = crypto_encrypt(c, m, mlen); if (!rc) { char key[KEY_BYTES + 1] = {0}; crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t *)&client_addr, sizeof(client_addr), NULL, 0); struct client_context *client = NULL; uv_mutex_lock(&mutex); cache_lookup(cache, key, (void *)&client); uv_mutex_unlock(&mutex); if (client == NULL) { client = new_client(); client->addr = client_addr; memcpy(client->key, key, sizeof(key)); uv_timer_init(watcher->loop, client->timer); uv_udp_init(watcher->loop, &client->server_handle); client->server_handle.data = client; uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb); uv_mutex_lock(&mutex); cache_insert(cache, client->key, (void *)client); uv_mutex_unlock(&mutex); } reset_timer(client); forward_to_server(server->server_addr, client, c, clen); } } }
int main(int argc, char **argv) { #define PORTSZ 32 char portname[PORTSZ]; max_fd = 0; /* No disk files on remote machine */ _fb_disk_enable = 0; memset((void *)clients, 0, sizeof(struct pkg_conn *) * MAX_CLIENTS); #ifdef SIGALRM (void)signal( SIGPIPE, SIG_IGN ); (void)signal( SIGALRM, sigalarm ); #endif /*alarm(1)*/ FD_ZERO(&select_list); fb_server_select_list = &select_list; fb_server_max_fd = &max_fd; #ifndef _WIN32 /* * Inetd Daemon. * Check to see if we were invoked by /etc/inetd. If so * we will have an open network socket on fd=0. Become * a Transient PKG server if this is so. */ netfd = 0; if ( is_socket(netfd) ) { init_syslog(); new_client( pkg_transerver( fb_server_pkg_switch, comm_error ) ); max_fd = 8; once_only = 1; main_loop(); return 0; } #endif /* for now, make them set a port_num, for usage message */ if ( !get_args( argc, argv ) || !port_set ) { (void)fputs(usage, stderr); return 1; } /* Single-Frame-Buffer Server */ if ( framebuffer != NULL ) { fb_server_retain_on_close = 1; /* don't ever close the frame buffer */ /* open a frame buffer */ if ( (fb_server_fbp = fb_open(framebuffer, width, height)) == FB_NULL ) bu_exit(1, NULL); max_fd = fb_set_fd(fb_server_fbp, &select_list); /* check/default port */ if ( port_set ) { if ( port < 1024 ) port += 5559; } snprintf(portname, PORTSZ, "%d", port); /* * Hang an unending listen for PKG connections */ if ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) bu_exit(-1, NULL); FD_SET(netfd, &select_list); V_MAX(max_fd, netfd); main_loop(); return 0; } #ifndef _WIN32 /* * Stand-Alone Daemon */ /* check/default port */ if ( port_set ) { if ( port < 1024 ) port += 5559; sprintf(portname, "%d", port); } else { snprintf(portname, PORTSZ, "%s", "remotefb"); } init_syslog(); while ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) { static int error_count=0; sleep(1); if (error_count++ < 60) { continue; } comm_error("Unable to start the stand-alone framebuffer daemon after 60 seconds, giving up."); return 1; } while (1) { int fbstat; struct pkg_conn *pcp; pcp = pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 ); if ( pcp == PKC_ERROR ) break; /* continue is unlikely to work */ if ( fork() == 0 ) { /* 1st level child process */ (void)close(netfd); /* Child is not listener */ /* Create 2nd level child process, "double detach" */ if ( fork() == 0 ) { /* 2nd level child -- start work! */ new_client( pcp ); once_only = 1; main_loop(); return 0; } else { /* 1st level child -- vanish */ return 1; } } else { /* Parent: lingering server daemon */ pkg_close(pcp); /* Daemon is not the server */ /* Collect status from 1st level child */ (void)wait( &fbstat ); } } #endif /* _WIN32 */ return 2; }
/* * Loop forever handling clients as they come and go. * Access to the framebuffer may be interleaved, if the user * wants it that way. */ static void main_loop(void) { int nopens = 0; int ncloses = 0; while ( !fb_server_got_fb_free ) { long refresh_rate = 60000000; /* old default */ fd_set infds; struct timeval tv; int i; if (fb_server_fbp) { if (fb_poll_rate(fb_server_fbp) > 0) refresh_rate = fb_poll_rate(fb_server_fbp); } infds = select_list; /* struct copy */ tv.tv_sec = 0L; tv.tv_usec = refresh_rate; if ((select( max_fd+1, &infds, (fd_set *)0, (fd_set *)0, (struct timeval *)&tv ) == 0)) { /* Process fb events while waiting for client */ /*printf("select timeout waiting for client\n");*/ if (fb_server_fbp) { if (fb_poll(fb_server_fbp)) { return; } } continue; } /* Handle any events from the framebuffer */ if (fb_is_set_fd(fb_server_fbp, &infds)) { fb_poll(fb_server_fbp); } /* Accept any new client connections */ if (netfd > 0 && FD_ISSET(netfd, &infds)) { new_client( pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 ) ); nopens++; } /* Process arrivals from existing clients */ /* First, pull the data out of the kernel buffers */ for (i = MAX_CLIENTS-1; i >= 0; i--) { if (clients[i] == NULL ) continue; if (pkg_process( clients[i] ) < 0) { fprintf(stderr, "pkg_process error encountered (1)\n"); } if (! FD_ISSET( clients[i]->pkc_fd, &infds )) continue; if (pkg_suckin( clients[i] ) <= 0) { /* Probably EOF */ drop_client( i ); ncloses++; continue; } } /* Second, process all the finished ones that we just got */ for (i = MAX_CLIENTS-1; i >= 0; i--) { if (clients[i] == NULL ) continue; if (pkg_process( clients[i] ) < 0) { fprintf(stderr, "pkg_process error encountered (2)\n"); } } if (once_only && nopens > 1 && ncloses > 1) return; } }