Exemplo n.º 1
0
/* Main server loop, uses select to listen/respond to requests */
static int server_loop(void)
{
    int rv, fd;

    while(1) {
        /* make sure listeneing server fd is in the set */
        read_fds = master_read_fds;

        /* block until we have new connection or data from client */
        rv = select(fd_max+1, &read_fds, NULL, NULL, NULL);
        if (rv == -1) {
            fsa_error(LOG_ERR, "select failed: %s", strerror(errno));
            return -1;
        }

        /* loop through all fds, check if any ready to be read */
        for (fd = 0; fd <= fd_max; fd++) {
            if (FD_ISSET(fd, &read_fds)) {
                if (fd == listener_fds[0]) {
                    /* new ipv4 client */
                    handle_new_connection(0); 
                }
                else if (fd == listener_fds[1]) {
                    /* new ipv6 client */
                    handle_new_connection(1); 
                }
                else {
                    /* client has data for us */
                    handle_client_data(fd);
                }
            }
        }
    }
}
Exemplo n.º 2
0
void handle_server_event(Connection *a_server)
{
    Client *client = NULL;

    if (connection_get_type(a_server) == TCP) {
        Connection *conn = connection_tcp_accept(connection_get_fd(a_server));
        if (conn) {
            client = client_create(conn);
            vector_add(_s_clients, client);
        }
    } else {
        char buf[BUF_SIZE] = {0};
        char straddr[BUF_SIZE] = {0};
        struct sockaddr_in *addr = NULL;
        connection_udp_receive_with_addr(a_server, buf, BUF_SIZE, (struct sockaddr **)&addr);
        assert(addr);
        client = vector_get_first_equal(_s_clients, addr, cmp_clients_by_addr);
        if (client == NULL) {
            Connection *cl_conn = connection_create_raw(UDP, connection_get_fd(a_server), addr);
            client = client_create(cl_conn);
            vector_add(_s_clients, client);
        }
        sprintf(straddr, "%s:%d", inet_ntoa(addr->sin_addr), addr->sin_port);
        handle_client_data(client, buf, straddr);
    }
}
Exemplo n.º 3
0
static void receive_tcp_client_data(Client *a_client)
{
    char buf[BUF_SIZE] = {0};
    char address[64] = {0};
    int res;

    res = connection_tcp_receive(a_client->conn, buf, BUF_SIZE);
    if (res) {
        vector_delete_first_equal(_s_clients, a_client, cmp_clients_by_ptr);
        char message[BUF_SIZE] = {0};
        sprintf(message, "Something happened. The client '%s' left the chat.",
                a_client->name);
        send_broadcast_msg(message);
        info("%s", message);
        client_destroy(a_client);
        return;
    }

    sprintf(address, "%s:%d", connection_get_address_str(a_client->conn),
            connection_get_port(a_client->conn));

    info("From address '%s' recived message '%s'", address, buf);

    handle_client_data(a_client, buf, address);
}
Exemplo n.º 4
0
/**
 * Reads the thread specific userdata to figure out what
 * we need to handle. Things that purely effect the network
 * stack should be handled here, but otherwise we should defer
 * to the connection handlers.
 */
static void invoke_event_handler(worker_ev_userdata* data) {
    // Get the offending handle
    ev_io *watcher = data->watcher;
    int fd = watcher->fd;

    // Check if this is either of the listeners
    if (watcher == &data->netconf->tcp_client) {
        // Accept the new client
        handle_new_client(fd, data);

        // Reschedule the listener
        schedule_async(data->netconf, SCHEDULE_WATCHER, watcher);
        return;

    // If it is write ready, dispatch the write handler
    }  else if (data->ready_events & EV_WRITE) {
        handle_client_writebuf(watcher, data);
        return;
    }

    // Check for UDP inbound
    if (watcher == &data->netconf->udp_client) {
        // Read the message and process
        if (!handle_udp_message(watcher, data)) {
            statsite_proxy_conn_handler handle = {data->netconf->config, data->netconf->proxy, watcher->data};
            handle_client_connect(&handle);
        }

        // Reschedule the listener
        schedule_async(data->netconf, SCHEDULE_WATCHER, watcher);
        return;
    }

    /*
     * If it is not a listener, it must be a connected
     * client. We should just read all the available data,
     * append it to the buffers, and then invoke the
     * connection handlers.
     */
    conn_info *conn = watcher->data;
    incref_client_connection(conn);

    if (!handle_client_data(watcher, data)) {
        statsite_proxy_conn_handler handle = {data->netconf->config, data->netconf->proxy, watcher->data};
        handle_client_connect(&handle);
    }

    // Reschedule the watcher, unless told otherwise.
    if (conn->should_schedule) {
        schedule_async(data->netconf, SCHEDULE_WATCHER, watcher);
    }
    decref_client_connection(conn);
}
Exemplo n.º 5
0
int main(int argc, char *argv[]) {
	main_thread = pthread_self();
	signal(SIGUSR1, &handle_signal);
	signal(SIGPIPE, SIG_IGN);
	message_queue_init(&io_queue, sizeof(struct io_op), 128);
	threadpool_init();
	int fd = open_http_listener();
	if(fd >= 0) {
		while(1) {
			fd_set rfds, wfds;
			int max_fd, r;
			main_blocked = 1;
			__sync_synchronize();
			service_io_message_queue();
			FD_ZERO(&rfds);
			FD_ZERO(&wfds);
			max_fd = 0;
			FD_SET(fd, &rfds);
			for(int i=0;i<FD_SETSIZE;++i) {
				if(client_data[i].state == CLIENT_READING) {
					FD_SET(i, &rfds);
					max_fd = i;
				} else if(client_data[i].state == CLIENT_WRITING) {
					FD_SET(i, &wfds);
					max_fd = i;
				}
			}
			max_fd = fd > max_fd ? fd : max_fd;
			r = select(max_fd+1, &rfds, &wfds, NULL, NULL);
			main_blocked = 0;
			__sync_synchronize();
			if(r < 0 && errno != EINTR) {
				perror("Error in select");
				return -1;
			}
			if(r > 0) {
				if(FD_ISSET(fd, &rfds)) {
					struct sockaddr_in peer_addr;
					socklen_t peer_len = sizeof(peer_addr);
					int cfd = accept(fd, (struct sockaddr *)&peer_addr, &peer_len);
					if(cfd >= 0) {
						int flags = fcntl(cfd, F_GETFL, 0);
						fcntl(fd, F_SETFL, flags | O_NONBLOCK);
						client_data[cfd].state = CLIENT_READING;
						client_data[cfd].pos = 0;
					}
				}
				for(int i=0;i<FD_SETSIZE;++i) {
					if(i != fd && FD_ISSET(i, &rfds)) {
						handle_client_data(i);
					} else if(i != fd && FD_ISSET(i, &wfds)) {
						int r = write(i, client_data[i].write_op->buf+client_data[i].write_op->pos, client_data[i].write_op->len-client_data[i].write_op->pos);
						if(r >= 0) {
							client_data[i].write_op->pos += r;
							if(client_data[i].write_op->pos == client_data[i].write_op->len) {
								client_data[i].state = CLIENT_INACTIVE;
								if(client_data[i].write_op->close_pending) {
									close(client_data[i].write_op->rfd);
									close(i);
								} else {
									struct www_op *message = message_queue_message_alloc_blocking(&worker_queue);
									message->operation = OP_READ_BLOCK;
									message->fd = i;
									message->rfd = client_data[i].write_op->rfd;
									message_queue_write(&worker_queue, message);
								}
								message_queue_message_free(&io_queue, client_data[i].write_op);
							}
						} else {
							close(client_data[i].write_op->rfd);
							close(i);
							message_queue_message_free(&io_queue, client_data[i].write_op);
							client_data[i].state = CLIENT_INACTIVE;
						}
					}
				}
			}
			service_io_message_queue();
		}
	} else {
		perror("Error listening on *:8080");
	}
}
Exemplo n.º 6
0
/*
 * Function     : main
 * Description  : entry point
 * Input params : argc, argv
 * Return       : void
 *
 */
int main(int argc, char* argv[])
{
    int fdmax;
    int fd = 0;

    int channel = INVALID_CHANNEL;
    int do_standalone_scan = FALSE;
    
    int optc;
    char *radio_ifname  = NULL;
    char *dev_ifname    = NULL;

    fd_set  master;
    fd_set  read_fds;

    ath_ssd_inet_t *pinet = GET_ADDR_OF_INETINFO(pinfo);
    ath_ssd_nlsock_t *pnl = GET_ADDR_OF_NLSOCKINFO(pinfo);

    /* use TCP by default */
    sock_type_t sock_type = SOCK_TYPE_UDP;

    while ((optc = getopt(argc, argv, "adc:gHhi:j:Tts:")) != -1) {
        switch (optc) {
            case 'a':
                pinfo->current_band = BAND_5GHZ;
                break;
            case 'c':
                pinfo->log_mode = atoi(optarg);
                break;    
            case 'd':
                debug = TRUE;
                break;
            case 'g':
                pinfo->current_band = BAND_2GHZ;
                break;
            case 'T':
            case 't':
                sock_type = SOCK_TYPE_TCP;
                break;
            case 'h':
            case 'H':
                print_usage();
                break;
            case 's':
                channel = atoi(optarg);
                if ((channel < 0 ) || (channel > CHANNEL_11)) {
                    print_usage();
                }
                do_standalone_scan = TRUE;
                break;
            case 'i':
                radio_ifname = optarg;
                break;
            case 'j':
                dev_ifname = optarg;
                break;
            case '?':
                if ((optopt == 's') || (optopt == 'i') || (optopt == 'j') || (optopt == 'c')) {
                    fprintf(stderr, "Option -%c requries an argument.\n", optopt);
                } else {
                    fprintf(stderr, "Unknown option '-%c'.\n", optopt);
                }
                exit(EXIT_FAILURE);
            default:
                break;
        }
    }

    /* init the socket type */
    pinfo->sock_type = sock_type;

    /* init the dwell interval */
    pinfo->dwell_interval = CHANNEL_NORMAL_DWELL_INTERVAL;

    /* init the current channel list */
    if (IS_BAND_5GHZ(pinfo)) {
        pinfo->channel_list = dot11a_channels;
        pinfo->max_channels = ARRAY_LEN(dot11a_channels);
    } else {
        pinfo->channel_list = dot11g_channels;
        pinfo->max_channels = ARRAY_LEN(dot11g_channels);
    }

    /* save the interface name */
    if (radio_ifname) {
        pinfo->radio_ifname = radio_ifname;
    } else {
        pinfo->radio_ifname = DEFAULT_RADIO_IFNAME;
    }

    if (dev_ifname) {
        pinfo->dev_ifname = dev_ifname;
    } else {
        pinfo->dev_ifname = DEFAULT_DEV_IFNAME;
    }

    if (CONFIGURED_SOCK_TYPE(pinfo) == SOCK_TYPE_TCP) {
        /* init TCP socket interface */
        if (init_inet_sockinfo(pinfo) == FAILURE) {
            exit(EXIT_FAILURE);
        }
    }
    else if (CONFIGURED_SOCK_TYPE(pinfo) == SOCK_TYPE_UDP) {
        /* init UDP socket interface */
        if (init_inet_dgram_sockinfo(pinfo) == FAILURE) {
            exit(EXIT_FAILURE);
        }
    } else {
        info("invalid socket type");
        exit(EXIT_FAILURE);
    }

    if (init_nl_sockinfo(pinfo) == FAILURE) {
        exit(EXIT_FAILURE);
    }

    FD_ZERO(&master);
    FD_ZERO(&read_fds);

    FD_SET(pnl->spectral_fd, &master);
    FD_SET(pinet->listener, &master);

    fdmax = (pinet->listener > pnl->spectral_fd)?pinet->listener:pnl->spectral_fd;

    signal(SIGINT, signal_handler);
    signal(SIGALRM, signal_handler);
    signal(SIGCHLD, signal_handler);
    signal(SIGTERM, signal_handler);
    signal(SIGHUP, signal_handler);

    info("server (built at %s %s )", __DATE__, __TIME__);
    info("interface     : %s", pinfo->radio_ifname);
    info("current band  : %s", (pinfo->current_band == BAND_5GHZ)?"5GHz ":"2.4GHz ");

    if (do_standalone_scan) {
        start_standalone_spectral_scan(pinfo, channel);
    }

    for (;;) {

        read_fds = master;

        if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
                continue;
        }

        for (fd = 0; fd <= fdmax; fd++) {
            if (FD_ISSET(fd, &read_fds)) {
                if (fd ==  pinet->listener ) {

                    if (CONFIGURED_SOCK_TYPE(pinfo) == SOCK_TYPE_UDP) {
                        if (handle_client_data(pinfo, fd) == -1) {
                            cleanup(pinfo);
                            exit(EXIT_FAILURE);
                        }
                    } else if (CONFIGURED_SOCK_TYPE(pinfo) == SOCK_TYPE_TCP) {
                        if (accept_new_connection(pinfo)) {
                            FD_SET(pinet->client_fd, &master);
                            fdmax = (pinet->client_fd > fdmax)?pinet->client_fd:fdmax;
                        }
                    }
                }
                else if (fd ==  pnl->spectral_fd) {
                        if (handle_spectral_data(pinfo) == FAILURE) {
                            cleanup(pinfo);
                            exit(EXIT_FAILURE);
                        }
                }
                else if ((fd == pinet->client_fd) &&
                         (CONFIGURED_SOCK_TYPE(pinfo) == SOCK_TYPE_TCP)) {
                        if (handle_client_data(pinfo, fd ) == -1) {
                            cleanup(pinfo);
                            exit(EXIT_FAILURE);
                        }
                }
            }
        }
    }
    return 0;
}