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
int main(void)
{
	BOOL bRet;
	HANDLE hRet;

	wsa_init();

	iocp = w_iocp_create();
	DIE(iocp == NULL, "w_iocp_create");

	/* Create server socket. */
	listenfd = tcp_create_listener(ECHO_LISTEN_PORT, DEFAULT_LISTEN_BACKLOG);
	DIE(listenfd == INVALID_SOCKET, "tcp_create_listener");

	hRet = w_iocp_add_handle(iocp, (HANDLE) listenfd);
	DIE(hRet != iocp, "w_iocp_add_handle");

	/* Use AcceptEx to schedule new connection acceptance. */
	create_iocp_accept();

	dlog(LOG_INFO, "Server waiting for connections on port %d\n", ECHO_LISTEN_PORT);

	/* server main loop */
	while (1) {
		OVERLAPPED *ovp;
		ULONG_PTR key;
		DWORD bytes;

		/* Wait for overlapped I/O. */
		bRet = w_iocp_wait(iocp, &bytes, &key, &ovp);
		if (bRet == FALSE) {
			DWORD err;

			err = GetLastError();
			if (err == ERROR_NETNAME_DELETED) {
				connection_remove((struct connection *) key);
				continue;
			}
			DIE(bRet == FALSE, "w_iocp_wait");
		}

		/*
		 * Switch I/O notification types. Consider
		 *   - new connection requests (on server socket);
		 *   - socket communication (on connection sockets).
		 */

		if (key == listenfd) {
			dlog(LOG_DEBUG, "New connection\n");
			handle_new_connection(ovp);
		}
		else {
			handle_aio((struct connection *) key, bytes, ovp);
		}
	}

	wsa_cleanup();

	return 0;
}
Exemplo n.º 3
0
int CommunicationServer::process_dispatcher(void) {
	// 
	int reuse_addr = 1, reuse_port = 1;
	// 
	sock = socket(AF_INET, SOCK_STREAM, 0);
	if(sock < 0) {
		perror("socket");
		exit(-1);
	}
	// 
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
	setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse_port, sizeof(reuse_port));
	setnonblocking(sock);
	// 
	struct sockaddr_in server_address;
	memset((char *) &server_address, 0, sizeof(server_address));
	server_address.sin_family			= AF_INET;
	server_address.sin_addr.s_addr	= htonl(INADDR_ANY);
	server_address.sin_port				= 6669;
	//
	if(bind(sock, (struct sockaddr *) &server_address, sizeof(server_address)) < 0) {
		perror("bind");
		close(sock);
		exit(-1);
	}
	//
	listen(sock, 1024);
	printf("process_dispatcher() up and running.\n\r");
	int highsock = sock;
	//
	memset((char *) &connectlist, 0, sizeof(connectlist));
	// 
	struct timeval timeout;
	int readsocks;
	while(1) {
		handle_new_connection();
		// 
		build_select_list();
		// 
		timeout.tv_sec = 0;
		timeout.tv_usec = 32;
		// 
		readsocks = select(highsock + 1, &socks, (fd_set *) 0, (fd_set *) 0, &timeout);
		// 
		if(readsocks < 0) {
			perror("select");
			continue;
		}
		if(readsocks == 0) {
			//printf("process_dispatcher() ticking ..\n\r");
			// write
			//handle_new_connection();
		} else {
			printf("select returned > 0\n\r");
			read_socks();
		}
	}
	return 0;
}
Exemplo n.º 4
0
void 
vrpn_Atmel::mainloop()
{
  if (_status == VRPN_ATMEL_STATUS_ERROR) {

    return;
  }
	
  // o_num_channel is used as reference against num_channel
  if (o_num_channel != num_channel) {

    num_channel = o_num_channel;
  }

  server_mainloop();
  
  // get the pending messages so that the buffer to write down is updated
  d_connection->mainloop();
  
  if ( ! d_connection->connected()) {

    return;
  }
  
  // it's the first time we are in mainloop after 
  if ( _status == VRPN_ATMEL_STATUS_WAITING_FOR_CONNECTION) {
	  
    if (handle_new_connection()) {
  
      _status = VRPN_ATMEL_STATUS_RUNNING;
    
      fprintf(stderr,"vrpn_Atmel: mainloop()\n");
      fprintf(stderr,"  new connection. status set to RUNNING\n");
    }
    else {
   
      _status = VRPN_ATMEL_STATUS_ERROR;
    
      fprintf(stderr,"vrpn_Atmel: mainloop()\n");
      fprintf(stderr,"  error handling new connection. status set to ERROR\n");
   
      return; 
    }
    
  }

  // do the read/write operations on the serial port   
  if ( ! mainloop_serial_io() ) {
    
    fprintf(stderr,"vrpn_Atmel: mainloop()\n");
    fprintf(stderr,"  error while io operations ERROR\n");

  }
  
  vrpn_Analog::report();
  //vrpn_Analog::report_changes();

  d_connection->mainloop();
}
Exemplo n.º 5
0
void StreamManager::handle_async_write_audio_header(asio::ip::tcp::socket *client, std::string request_headers, const boost::system::error_code &error, std::size_t transferred)
{
	if(error || transferred <= 0)
	{
		HandleError();
		return;
	}

	handle_new_connection(client, request_headers);
}
Exemplo n.º 6
0
int handle_events(int fd, int event_type)
{
	if (fd == g_acceptor_fd) {
		handle_new_connection(fd, event_type);
	}
	else {
		handle_socket_events(fd, event_type);
	}

	return 0;
}
Exemplo n.º 7
0
void CommunicationServer::read_socks(void) {
	int listnum;
	if(FD_ISSET(sock, &socks)) {
		printf("accepting..\n\r");
		handle_new_connection();
	}
	for(listnum = 0; listnum < 1024; listnum++) {
		if(FD_ISSET(connectlist[listnum], &socks))
			deal_with_data(listnum);
	}
	return;
}
Exemplo n.º 8
0
void StreamManager::new_connection(asio::ip::tcp::socket *client_socket, const std::string &request_headers)
{
	auto header_buffer_lenght = 0;
	auto header_buffer = _audio_output_stream->GetHeader(header_buffer_lenght);

	if (header_buffer_lenght > 0)
	{
		async_write_audio_header(client_socket, request_headers, header_buffer, header_buffer_lenght);
	}
	else
	{
		handle_new_connection(client_socket, request_headers);
	}
}
/************************************************************************** 
 * Get an incomming request buffer from a client,
 * Provide a handle on the connection on which it was received. 
 *
 * The server takes this oportunity to process new connection
 * requests on the name sockets first. These requests are accept()ed 
 * and an unused socket is then used for the dialoge with a that particular
 * client.
 **************************************************************************/
void server_comm_get_request(int *conn, char *req_buf)
{
  int i, nr, not_done = 1;
  fd_set read_selects;

  if (!srv_comm_inited)
    server_comm_init();

  /* loop, processing new connection requests until a client buffer
     is read in on an existing connection. */

  while (not_done) {
    
    /* Set up the socket descriptor mask for the select.
       copy srv_read_set, into the local copy */

    FD_ZERO(&read_selects);
    for (i = 0; i < MAX_NUM_CONNECTIONS; i++) {
      if (FD_ISSET(srv_sock[i], &srv_read_set))
	FD_SET(srv_sock[i], &read_selects);
    }
    
    /* Poll active connections using select() */
    if ((nr = select(FD_SETSIZE,
	   &read_selects, 
	   (fd_set *)NULL,
	   (fd_set *)NULL,
	   (struct timeval *)NULL)) <= 0) {
      perror("Select new reads");
      exit(1);
    }

    if (FD_ISSET(srv_sock[0], &read_selects)) {

       /* Handle the case of a new connection request on the named socket */
      handle_new_connection();

    } else {

      /* Read data from client specific descriptor */
      if (handle_new_request(read_selects, &conn, &req_buf) == 0)
	not_done = 0;
    }

  } /* While not_done */

}
Exemplo n.º 10
0
/**
 * Updates the socket server. This method needs to be called periodically.
 * @param transport Transport handle
 */
lwpb_err_t lwpb_transport_socket_server_update(lwpb_transport_t transport)
{
    struct lwpb_transport_socket_server *socket_server =
        (struct lwpb_transport_socket_server *) transport;
    int i;
    int socket;
    struct timeval timeout;
    fd_set read_fds;
    int high;
    
    if (socket_server->socket == -1)
        return LWPB_ERR_SOCKET_CLOSED;
    
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    
    // Create set of active sockets
    high = socket_server->socket;
    FD_ZERO(&read_fds);
    FD_SET(socket_server->socket, &read_fds);
    for (i = 0; i < LWPB_TRANSPORT_SOCKET_SERVER_CONNS; i++)
        if (socket_server->conns[i].socket != -1) {
            FD_SET(socket_server->conns[i].socket, &read_fds);
            high = socket_server->conns[i].socket;
        }
    
    // Wait for a socket to get active
    i = select(high + 1, &read_fds, NULL, NULL, &timeout);
    if (i < 0)
        LWPB_FAIL("select() failed");
    if (i == 0)
        return LWPB_ERR_OK;
    
    // Accept new connections
    if (FD_ISSET(socket_server->socket, &read_fds))
        handle_new_connection(socket_server);
    
    // Handle active connections
    for (i = 0; i < LWPB_TRANSPORT_SOCKET_SERVER_CONNS; i++) {
        struct lwpb_socket_server_conn *conn = &socket_server->conns[i];
        if (conn->socket != -1 && FD_ISSET(conn->socket, &read_fds))
            handle_connection(socket_server, conn);
    }
    
    return LWPB_ERR_OK;
}
Exemplo n.º 11
0
void readSocks() //check all the sockets
{
	int x;	    
	
    if (FD_ISSET(sockfd, &readfds))
    {
		handle_new_connection();
    }
	
	
	// Run through our sockets and check to see if anything happened with them
	for (x = 0; x < MAX_USERS; x++) 
    {
		if (FD_ISSET(fd[x], &readfds))
        {
            printf("handling user: %d\n", x);
			handleData(x);
        }
	} 
}
Exemplo n.º 12
0
void read_socks(User *listUs,QA *listQA) {
	int listnum;	     /* Current item in connectlist for for loops */
	
	/* If a client is trying to connect() to our listening
		socket, select() will consider that as the socket
		being 'readable'. Thus, if the listening socket is
		part of the fd_set, we need to accept a new connection. */
	
	if (FD_ISSET(sock,&socks))
		handle_new_connection();
	/* Now check connectlist for available data */
	
	/* Run through our sockets and check to see if anything
		happened with them, if so 'service' them. */
	
	for (listnum = 0; listnum < BACKLOG; listnum++) {
		if (FD_ISSET(connectlist[listnum],&socks))
		  deal_with_data(listnum,listUs,listQA);
	} /* for (all entries in queue) */
}
int server_loop(int request_sock)
{
    int i, num_fds;
    fd_set read_fds;


    read_fds = master_fds;

    printf("Now waiting for data...\n");
    num_fds = select(select_max_fds, &read_fds, NULL, NULL, &timeout);
    printf("Select returned! Got activity on %d sockets.\n", num_fds);

    if (num_fds < 0) {
        perror("select");
        return -1;
    }

    if (num_fds == 0) {
        /* Select timed out. Shut down server. */
        return -2;
    }

    for (i = 0; i < select_max_fds; i++) {
        if (FD_ISSET (i, &read_fds)) {
            if (i == request_sock) {
                /* Event on server socket.
                 * There is a new incoming connection */
                if(numsocks >= maxsocks) {
                    fprintf(stderr,
                            "No more space for sockets.\n");
                    return -1;
                }
                handle_new_connection(request_sock);
            } else {
                /* Event on existing client socket. */
                handle_data(i);
            }
        }
    }
    return 0;
}
Exemplo n.º 14
0
/*
 * Accept and authenticate a new client connection on one of the listening sockets.
 */
static void
server_socket_event(int server_fd, int epfd)
{
    struct epoll_event ev;
    struct sockaddr_storage addr;
    int newfd, opt_enable = 1;
    socklen_t addrlen = sizeof (addr);

    memset(&addr, 0, addrlen);
    newfd =
        accept4(server_fd, (struct sockaddr *)&addr, &addrlen,
                SOCK_NONBLOCK | SOCK_CLOEXEC);
    if (newfd == -1)    /* maybe the connection attempt was aborted early? */
        return;

    /* no need to complain if this setsockopt fails; TCP_NODELAY doesn't exist
       for AF_UNIX sockets. */
    setsockopt(newfd, IPPROTO_TCP, TCP_NODELAY, &opt_enable, sizeof (int));

    if (addr.ss_family == AF_UNIX) {
        /* unix sockets don't have defer_accept, so the auth data might not be
           ready yet. Additionally, as the socket is local, it gets a higher
           level of trust. */
        ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
        ev.data.ptr = NULL;
        ev.data.fd = newfd;
        if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &ev) == -1) {
            log_msg("Error in epoll_ctl for %s: %s", addr2str(&addr),
                    strerror(errno));
            close(newfd);
            return;
        }
        map_fd_to_client(newfd, &new_connection_dummy);
        return;
    } else
        handle_new_connection(newfd, epfd);
}
Exemplo n.º 15
0
int main(int argc, char *argv[])
{
	int error __unused, i, r, s;
	FILE *pidf;
	int ch = 0;

	while ((ch = getopt(argc, argv, "d")) != -1) {
		switch(ch) {
		case 'd':
			debugopt = 1;
			break;
		default:
			usage();
			/* NOT REACHED */
		}
	}
	argc -= optind;
	argv += optind;

	TAILQ_INIT(&pdev_array_list);
	TAILQ_INIT(&udev_monitor_list);

	r = ignore_signal(SIGPIPE);
	if (r != 0)
		err(1, "could not ignore_signal SIGPIPE");

	r = pthread_mutex_init(&(monitor_lock), NULL);
	if (r != 0)
		err(1, "could not allocate a pthread_mutex");

	if ((udevfd = open(UDEV_DEVICE_PATH, O_RDWR | O_NONBLOCK)) == -1)
		err(1, "%s", UDEV_DEVICE_PATH);
	unblock_descriptor(udevfd);

	s = init_local_server(LISTEN_SOCKET_FILE, SOCK_STREAM, 0);
	if (s < 0)
		err(1, "init_local_server");

	pidf = fopen("/var/run/udevd.pid", "w");
#if 0
	if (pidf == NULL)
		err(1, "pidfile");
#endif

	set_signal(SIGTERM, killed);
	set_signal(SIGHUP, hangup);

	if (debugopt == 0)
		if (daemon(0, 0) == -1)
			err(1, "daemon");

	if (pidf != NULL) {
		fprintf(pidf, "%ld\n", (long)getpid());
		fclose(pidf);
	}

	syslog(LOG_ERR, "udevd started");

	pdev_array_entry_insert(udev_getdevs(udevfd));

	memset(fds, 0 , sizeof(fds));
	fds[UDEV_DEVICE_FD_IDX].fd = udevfd;
	fds[UDEV_DEVICE_FD_IDX].events = POLLIN;
	fds[UDEV_SOCKET_FD_IDX].fd = s;
	fds[UDEV_SOCKET_FD_IDX].events = POLLIN | POLLPRI;

	for (;;) {
		r = poll(fds, NFDS, -1);
		if (r < 0) {
			if (hangup_ongoing == 0) {
				if (errno == EINTR) {
					usleep(5000);
					continue;
				} else {
					err(1, "polling...");
				}
			} else {
				usleep(20000); /* 20 ms */
				continue;
			}
		}

		for (i = 0; (i < NFDS) && (r > 0); i++) {
			if (fds[i].revents == 0)
				continue;

			--r;
			switch (i) {
			case UDEV_DEVICE_FD_IDX:
				udev_read_event(udevfd);
				break;
			case UDEV_SOCKET_FD_IDX:
				handle_new_connection(s);
				break;
			default:
				break;
			}
		}
	}

	syslog(LOG_ERR, "udevd is exiting normally");
	return 0;
}
Exemplo n.º 16
0
/*
 * The server's core. Creates the configured listening sockets and then
 * enters the server event loop from which all clients are served.
 */
int
runserver(void)
{
    int i, ipv4fd, ipv6fd, unixfd, epfd, nfds, timeout, fd, childstatus;
    struct epoll_event events[MAX_EVENTS];
    struct client_data *client;
    struct timeval sigtime, curtime, tmp;

    fd_to_client_max = 64;      /* will be doubled every time it becomes too
                                   small */
    fd_to_client = malloc(fd_to_client_max * sizeof (struct client_data *));

    epfd = epoll_create1(EPOLL_CLOEXEC);
    if (epfd == -1) {
        log_msg("Error in epoll_create1");
        return FALSE;
    }

    if (!setup_server_sockets(&ipv4fd, &ipv6fd, &unixfd, epfd))
        return FALSE;

    /* 
     * server event loop
     */
    while (1) { /* loop exit via "goto finally" */
        timeout = 10 * 60 * 1000;
        if (termination_flag) {
            if (termination_flag == 1)  /* signal didn't interrupt epoll_wait */
                trigger_server_shutdown(&sigtime, &ipv4fd, &ipv6fd, &unixfd);
            gettimeofday(&curtime, NULL);
            /* calculate the elapsed time since the quit request */
            timersub(&curtime, &sigtime, &tmp);
            timeout = 5000 - (1000 * tmp.tv_sec) - (tmp.tv_usec / 1000);
            if (timeout < 0)
                timeout = 0;
        }

        /* make sure child processes are cleaned up */
        waitpid(-1, &childstatus, WNOHANG);

        nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
        if (nfds == -1) {
            if (errno != EINTR) {       /* serious problem */
                log_msg("Error from epoll_wait in main event loop: %s",
                        strerror(errno));
                goto finally;
            }

            /* some signal - SIGTERM? */
            if (!termination_flag)
                continue;

            /* begin server shutdown sequence */
            if (!trigger_server_shutdown(&sigtime, &ipv4fd, &ipv6fd, &unixfd))
                continue;
            else
                goto finally;
        } else if (nfds == 0) { /* timeout */
            if (!termination_flag)
                log_msg(" -- mark (no activity for 10 minutes) --");
            else        /* shutdown timer has run out */
                goto finally;
            continue;
        }

        for (i = 0; i < nfds; i++) {
            fd = events[i].data.fd;

            if (fd == ipv4fd || fd == ipv6fd || fd == unixfd) {
                /* server socket ready for accept */
                server_socket_event(fd, epfd);
                continue;
            }

            /* activity on a client socket or pipe */
            client = fd_to_client[fd];
            /* was this fd closed while handling a prior event? */
            if (!client)
                continue;

            switch (client->state) {
            case NEW_CONNECTION:
                if (events[i].events & EPOLLERR ||      /* error */
                    events[i].events & EPOLLHUP ||      /* connection closed */
                    events[i].events & EPOLLRDHUP)      /* connection closed */
                    close(fd);
                else if (events[i].events & EPOLLIN)
                    handle_new_connection(fd, epfd);
                break;

            case CLIENT_DISCONNECTED:
                /* When the client is disconnected, activity usually only
                   happens on the pipes: either the game process is closing
                   them because the idle timeout expired or shutdown was
                   requested via a signal. */
                if (events[i].events & EPOLLERR ||      /* error */
                    events[i].events & EPOLLHUP ||      /* connection closed */
                    events[i].events & EPOLLRDHUP)      /* connection closed */
                    cleanup_game_process(client, epfd);
                else if (events[i].events & EPOLLIN) {
                    /* Perhaps the game process was just writing data to the
                       pipe when the client disconnected. There is nothing we
                       can do with this data here, but we don't want to kill
                       the game either, so just read and discard the data. */
                    char buf[2048];
                    int ret;

                    do {
                        ret = read(fd, buf, 2048);
                    } while (ret == 2048);
                }
                break;

            case CLIENT_CONNECTED:
                handle_communication(fd, epfd, events[i].events);
                break;
            }
            if (termination_flag && client_count == 0)
                goto finally;
        }       /* for */
    }   /* while(1) */

finally:
    while (disconnected_list_head.next)
        cleanup_game_process(disconnected_list_head.next, epfd);
    while (connected_list_head.next)
        cleanup_game_process(connected_list_head.next, epfd);

    close(epfd);
    if (ipv4fd != -1)
        close(ipv4fd);
    if (ipv6fd != -1)
        close(ipv6fd);
    if (unixfd != -1)
        close(unixfd);
    free(fd_to_client);

    return TRUE;
}
Exemplo n.º 17
0
static int32_t
qb_ipcs_us_connection_acceptor(int fd, int revent, void *data)
{
	struct sockaddr_un un_addr;
	int32_t new_fd;
	struct qb_ipcs_service *s = (struct qb_ipcs_service *)data;
	int32_t res;
	struct qb_ipc_connection_request setup_msg;
	struct ipc_auth_ugp ugp;
	socklen_t addrlen = sizeof(struct sockaddr_un);

	if (revent & (POLLNVAL | POLLHUP | POLLERR)) {
		/*
		 * handle shutdown more cleanly.
		 */
		return -1;
	}

retry_accept:
	errno = 0;
	new_fd = accept(fd, (struct sockaddr *)&un_addr, &addrlen);
	if (new_fd == -1 && errno == EINTR) {
		goto retry_accept;
	}

	if (new_fd == -1 && errno == EBADF) {
		qb_util_perror(LOG_ERR,
			       "Could not accept client connection from fd:%d",
			       fd);
		return -1;
	}
	if (new_fd == -1) {
		qb_util_perror(LOG_ERR, "Could not accept client connection");
		/* This is an error, but -1 would indicate disconnect
		 * from the poll loop
		 */
		return 0;
	}

	res = qb_sys_fd_nonblock_cloexec_set(new_fd);
	if (res < 0) {
		close(new_fd);
		/* This is an error, but -1 would indicate disconnect
		 * from the poll loop
		 */
		return 0;
	}

	res = qb_ipcs_uc_recv_and_auth(new_fd, &setup_msg, sizeof(setup_msg),
				       &ugp);
	if (res < 0) {
		close(new_fd);
		/* This is an error, but -1 would indicate disconnect
		 * from the poll loop
		 */
		return 0;
	}

	if (setup_msg.hdr.id == QB_IPC_MSG_AUTHENTICATE) {
		(void)handle_new_connection(s, res, new_fd, &setup_msg,
					    sizeof(setup_msg), &ugp);
	} else {
		close(new_fd);
	}

	return 0;
}
Exemplo n.º 18
0
void handle_packet(apacket *p, atransport *t)
{
    D("handle_packet() %c%c%c%c", ((char*) (&(p->msg.command)))[0],
            ((char*) (&(p->msg.command)))[1],
            ((char*) (&(p->msg.command)))[2],
            ((char*) (&(p->msg.command)))[3]);
    print_packet("recv", p);

    switch(p->msg.command){
    case A_SYNC:
        if (p->msg.arg0){
            send_packet(p, t);
#if ADB_HOST
            send_connect(t);
#endif
        } else {
            t->connection_state = kCsOffline;
            handle_offline(t);
            send_packet(p, t);
        }
        return;

    case A_CNXN:  // CONNECT(version, maxdata, "system-id-string")
        handle_new_connection(t, p);
        break;

    case A_AUTH:
        if (p->msg.arg0 == ADB_AUTH_TOKEN) {
            t->connection_state = kCsUnauthorized;
            send_auth_response(p->data, p->msg.data_length, t);
        } else if (p->msg.arg0 == ADB_AUTH_SIGNATURE) {
            if (adb_auth_verify(t->token, sizeof(t->token), p->data, p->msg.data_length)) {
                adb_auth_verified(t);
                t->failed_auth_attempts = 0;
            } else {
                if (t->failed_auth_attempts++ > 256) adb_sleep_ms(1000);
                send_auth_request(t);
            }
        } else if (p->msg.arg0 == ADB_AUTH_RSAPUBLICKEY) {
            adb_auth_confirm_key(p->data, p->msg.data_length, t);
        }
        break;

    case A_OPEN: /* OPEN(local-id, 0, "destination") */
        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 == 0) {
            char *name = (char*) p->data;
            name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0;
            asocket* s = create_local_service_socket(name, t);
            if (s == nullptr) {
                send_close(0, p->msg.arg0, t);
            } else {
                s->peer = create_remote_socket(p->msg.arg0, t);
                s->peer->peer = s;
                send_ready(s->id, s->peer->id, t);
                s->ready(s);
            }
        }
        break;

    case A_OKAY: /* READY(local-id, remote-id, "") */
        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
            asocket* s = find_local_socket(p->msg.arg1, 0);
            if (s) {
                if(s->peer == 0) {
                    /* On first READY message, create the connection. */
                    s->peer = create_remote_socket(p->msg.arg0, t);
                    s->peer->peer = s;
                    s->ready(s);
                } else if (s->peer->id == p->msg.arg0) {
                    /* Other READY messages must use the same local-id */
                    s->ready(s);
                } else {
                    D("Invalid A_OKAY(%d,%d), expected A_OKAY(%d,%d) on transport %s",
                      p->msg.arg0, p->msg.arg1, s->peer->id, p->msg.arg1, t->serial);
                }
            } else {
                // When receiving A_OKAY from device for A_OPEN request, the host server may
                // have closed the local socket because of client disconnection. Then we need
                // to send A_CLSE back to device to close the service on device.
                send_close(p->msg.arg1, p->msg.arg0, t);
            }
        }
        break;

    case A_CLSE: /* CLOSE(local-id, remote-id, "") or CLOSE(0, remote-id, "") */
        if (t->online && p->msg.arg1 != 0) {
            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
            if (s) {
                /* According to protocol.txt, p->msg.arg0 might be 0 to indicate
                 * a failed OPEN only. However, due to a bug in previous ADB
                 * versions, CLOSE(0, remote-id, "") was also used for normal
                 * CLOSE() operations.
                 *
                 * This is bad because it means a compromised adbd could
                 * send packets to close connections between the host and
                 * other devices. To avoid this, only allow this if the local
                 * socket has a peer on the same transport.
                 */
                if (p->msg.arg0 == 0 && s->peer && s->peer->transport != t) {
                    D("Invalid A_CLSE(0, %u) from transport %s, expected transport %s",
                      p->msg.arg1, t->serial, s->peer->transport->serial);
                } else {
                    s->close(s);
                }
            }
        }
        break;

    case A_WRTE: /* WRITE(local-id, remote-id, <data>) */
        if (t->online && p->msg.arg0 != 0 && p->msg.arg1 != 0) {
            asocket* s = find_local_socket(p->msg.arg1, p->msg.arg0);
            if (s) {
                unsigned rid = p->msg.arg0;
                p->len = p->msg.data_length;

                if (s->enqueue(s, p) == 0) {
                    D("Enqueue the socket");
                    send_ready(s->id, rid, t);
                }
                return;
            }
        }
        break;

    default:
        printf("handle_packet: what is %08x?!\n", p->msg.command);
    }

    put_apacket(p);
}
Exemplo n.º 19
0
static int32_t
process_auth(int32_t fd, int32_t revents, void *d)
{
	struct ipc_auth_data *data = (struct ipc_auth_data *) d;

	int32_t res = 0;
#ifdef SO_PASSCRED
	int off = 0;
#endif

	if (data->s->server_sock == -1) {
		qb_util_log(LOG_DEBUG, "Closing fd (%d) for server shutdown", fd);
		res = -ESHUTDOWN;
		goto cleanup_and_return;
	}

	if (revents & POLLNVAL) {
		qb_util_log(LOG_DEBUG, "NVAL conn fd (%d)", fd);
		res = -EINVAL;
		goto cleanup_and_return;
	}
	if (revents & POLLHUP) {
		qb_util_log(LOG_DEBUG, "HUP conn fd (%d)", fd);
		res = -ESHUTDOWN;
		goto cleanup_and_return;
	}
	if ((revents & POLLIN) == 0) {
		return 0;
	}

	res = qb_ipc_us_recv_msghdr(data);
	if (res == -EAGAIN) {
		/* yield to mainloop, Let mainloop call us again */
		return 0;
	}

	if (res != data->len) {
		res = -EIO;
		goto cleanup_and_return;
	}

	res = qb_ipc_auth_creds(data);

cleanup_and_return:
#ifdef SO_PASSCRED
	setsockopt(data->sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off));
#endif

	(void)data->s->poll_fns.dispatch_del(data->sock);

	if (res < 0) {
		close(data->sock);
	} else if (data->msg.req.hdr.id == QB_IPC_MSG_AUTHENTICATE) {
		(void)handle_new_connection(data->s, res, data->sock, &data->msg, data->len, &data->ugp);
	} else {
		close(data->sock);
	}
	destroy_ipc_auth_data(data);

	return 1;
}
Exemplo n.º 20
0
int main(int argc, char *argv[])
{
  puts("Starting server.");

  fd_set file_descriptors;

  connection_info server_info;

  int i;


  if (argc != 4)
  {
    fprintf(stderr, "Usage:./%s <server_ip> <server_port> <max_client> \n", argv[0]);
    exit(1);
  }
  MAX_CLIENTS=atoi(argv[3]);
  //check the max clients
  //printf("%d",MAX_CLIENTS);

  connection_info *clients=(connection_info*)malloc(MAX_CLIENTS*sizeof(connection_info));
  
  
  for(i = 0; i < MAX_CLIENTS; i++)
  {
    clients[i].socket = 0;
  }
  
  
  initialize_server(&server_info, atoi(argv[2]));

  while(true)
  {
    int max_fd = construct_fd_set(&file_descriptors, &server_info, clients);

    if(select(max_fd+1, &file_descriptors, NULL, NULL, NULL) < 0)
    {
      perror("Select Failed");
      stop_server(clients);
    }

    if(FD_ISSET(STDIN_FILENO, &file_descriptors))
    {
      handle_user_input(clients);
    }

    if(FD_ISSET(server_info.socket, &file_descriptors))
    {
      handle_new_connection(&server_info, clients);
    }

    for(i = 0; i < MAX_CLIENTS; i++)
    {
      if(clients[i].socket > 0 && FD_ISSET(clients[i].socket, &file_descriptors))
      {
        handle_client_message(clients, i);
      }
    }
  }

  return 0;
}
Exemplo n.º 21
0
/** @brief API for add an incoming segment **/
int ntoh_tcp_add_segment ( pntoh_tcp_session_t session , pntoh_tcp_stream_t stream , struct ip *ip , size_t len , void *udata )
{
	size_t				iphdr_len = 0;
	size_t				tcphdr_len = 0;
	size_t				payload_len = 0;
	struct tcphdr			*tcp = 0;
	pntoh_tcp_peer_t		origin = 0;
	pntoh_tcp_peer_t		destination = 0;
	unsigned int			tstamp = 0;
	int				ret = NTOH_OK;
	pntoh_tcp_segment_t		segment = 0;
    int who;

	if ( !stream || !session )
		return NTOH_ERROR_PARAMS;

	/* verify IP header */
	if ( !ip ) // no ip header
		return NTOH_INCORRECT_IPHEADER;

	if ( len <= sizeof(struct ip) ) // no data
		return NTOH_INCORRECT_LENGTH;

	if ( ( iphdr_len = 4 * ( ip->ip_hl ) ) < sizeof(struct ip) ) // incorrect ip header length
		return NTOH_INCORRECT_IP_HEADER_LENGTH;

	if ( len < ntohs( ip->ip_len ) ) // incorrect capture length
		return NTOH_NO_ENOUGH_DATA;

	if ( ip->ip_v != 4 ) // only handle IPv4
		return NTOH_NOT_IPV4;

	/* check IP addresses */
	if ( !(
			( stream->client.addr == ip->ip_src.s_addr && stream->server.addr == ip->ip_dst.s_addr ) ||
			( stream->client.addr == ip->ip_dst.s_addr && stream->server.addr == ip->ip_src.s_addr )
		))
		return NTOH_IP_ADDRESSES_MISMATCH;

	if ( ip->ip_p != IPPROTO_TCP )
		return NTOH_NOT_TCP;

	tcp = (struct tcphdr*) ( (unsigned char*)ip + iphdr_len );

	/* check TCP header */
    if ( ( tcphdr_len = tcp->th_off * 4 ) < sizeof(struct tcphdr) )
            return NTOH_INCORRECT_TCP_HEADER_LENGTH;

	if ( !tcp->th_flags || tcp->th_flags == 0xFF )
		return NTOH_INVALID_FLAGS;

	lock_access ( &stream->lock );

    /* check TCP ports */
    if ( !(
    		( tcp->th_dport == stream->tuple.dport && tcp->th_sport == stream->tuple.sport ) ||
    		( tcp->th_dport == stream->tuple.sport && tcp->th_sport == stream->tuple.dport )
    	))
    	return NTOH_TCP_PORTS_MISMATCH;

    payload_len = ntohs(ip->ip_len) - iphdr_len - tcphdr_len;

    /* get origin and destination */
    if ( stream->tuple.source == ip->ip_src.s_addr )
    {
    	origin = &stream->client;
    	destination = &stream->server;
        who = NTOH_SENT_BY_CLIENT;
    }else{
    	origin = &stream->server;
    	destination = &stream->client;
        who = NTOH_SENT_BY_SERVER;
    }

    get_timestamp ( tcp , tcphdr_len , &tstamp );

    /* PAWS check */
    if ( tstamp > 0 && origin->lastts > 0 )
    {
    	if ( tstamp < origin->lastts )
    	{
    		ret = NTOH_PAWS_FAILED;
    		goto exitp;
    	}

        if ( ntohl(tcp->th_seq) <= origin->next_seq )
        	origin->lastts = tstamp;

    }else if ( tstamp > 0 && !(origin->lastts) )
    	origin->lastts = tstamp;

    if ( origin->next_seq > 0 && (origin->isn - ntohl ( tcp->th_seq ) ) < origin->next_seq )
    {
    	ret = NTOH_TOO_LOW_SEQ_NUMBER;
    	goto exitp;
    }

    if ( destination->next_seq > 0 && (origin->ian - ntohl(tcp->th_ack) ) < destination->next_seq )
    {
    	ret = NTOH_TOO_LOW_ACK_NUMBER;
    	goto exitp;
    }

    /* @todo some TCP/IP stacks implementations overloads the MSS on certain segments */
    /*if ( origin->mss > 0 && payload_len > origin->mss )
    	return NTOH_SEGMENT_EXCEEDS_MSS;*/

    /* switch between connection status */
    switch ( stream->status )
    {
    	case NTOH_STATUS_CLOSED:
    	case NTOH_STATUS_SYNSENT:
    	case NTOH_STATUS_SYNRCV:
    		if ( payload_len > 0 )
    		{
    			ret = NTOH_HANDSHAKE_FAILED;
    			goto exitp;
    		}

    		ret = handle_new_connection ( stream , tcp , origin ,  destination , udata );
    		if ( ret == NTOH_OK )
    		{
    			if ( origin->receive )
    			{
    				if ( stream->status == NTOH_STATUS_ESTABLISHED )
    					((pntoh_tcp_callback_t)stream->function) ( stream , origin , destination , 0 , NTOH_REASON_SYNC , NTOH_REASON_ESTABLISHED );
    				else
    					((pntoh_tcp_callback_t)stream->function) ( stream , origin , destination , 0 , NTOH_REASON_SYNC , NTOH_REASON_SYNC );
    			}
    		}else{
    			lock_access ( &session->lock );
    			delete_stream ( session , &stream , NTOH_REASON_SYNC , ret );
    			unlock_access ( &session->lock );
    		}

    		break;

    	case NTOH_STATUS_ESTABLISHED:
    		ret = handle_established_connection ( session , stream , tcp , payload_len , origin , destination , udata, who );
    		break;

    	default:
    		segment = new_segment( ntohl ( tcp->th_seq ) - origin->isn , ntohl ( tcp->th_ack ) - origin->ian , payload_len , tcp->th_flags , udata );
    		handle_closing_connection ( session , stream , origin , destination , segment, who );

    		if ( stream->status == NTOH_STATUS_CLOSED )
    		{
    			lock_access ( &session->lock );
    			__tcp_free_stream ( session , &stream , NTOH_REASON_SYNC , NTOH_REASON_CLOSED );
    			unlock_access ( &session->lock );
    			stream = 0;
    		}
    		break;
    }

	if ( ret == NTOH_OK )
	{
		if ( stream != 0 )
			gettimeofday ( & (stream->last_activ) , 0 );

		if ( payload_len == 0 )
			ret = NTOH_SYNCHRONIZING;
	}

exitp:
	if ( stream != 0 )
		unlock_access ( &stream->lock );

	return ret;
}
Exemplo n.º 22
0
int epoll_server( int sockfd )
{
	#define EVENTS_MAX 100
	int epfd = epoll_create( EVENTS_MAX );
	if( epfd < 0 )
	{
		SERVER_DEBUG( "epoll_create error:%s\n", strerror( errno ) );	
		return -1;
	}

	struct epoll_event epollev;
	epollev.events = EPOLLIN;
	epollev.data.fd = sockfd;
	if( epoll_ctl( epfd, EPOLL_CTL_ADD, sockfd, &epollev) < 0 )
	{
		SERVER_DEBUG( "epoll_ctl error:%s\n", strerror( errno ) );	
		close( epfd );
		return -1;
	}
	
	struct epoll_event events[EVENTS_MAX];
	int connection = 0;
	while( 1 )
	{
		#define TIME_OUT 5000
		int ret = epoll_wait( epfd, events, EVENTS_MAX, TIME_OUT );
		SERVER_DEBUG( "epoll_wait ret:%d\n", ret );
		if( ret < 0 )
		{
			SERVER_DEBUG( "epoll_wait error:%s\n", strerror( errno ) );	
			close( epfd );
			//handle other fdes
			return -1;
		} else if( 0 == ret ) {
			SERVER_DEBUG( "TIME_OUT,listenning...\n" );
			continue;
		} else {
			int i = 0;
			for( i = 0; i < ret; ++i )
			{
				if( events[i].data.fd == sockfd )
				{
					//accept new connection	
					int sockfd_new = handle_new_connection( sockfd );
					if( sockfd_new < 0 )
					{
						SERVER_DEBUG( "handle_new_connection error\n" );
						return -1;
					}
					
					//epollev.events = EPOLLIN|EPOLLOUT|EPOLLET;
					epollev.events = EPOLLIN|EPOLLET;
					epollev.data.fd = sockfd_new;
					if( epoll_ctl( epfd, EPOLL_CTL_ADD, sockfd_new, &epollev) < 0 )
					{
						SERVER_DEBUG( "epoll_ctl error:%s\n", strerror( errno ) );	
						close( epfd );
						return -1;
					}
						
					SERVER_DEBUG( "total connections:%d\n", ++connection );
				} else {
					//read-write
					int sockfd = events[i].data.fd;

					char buffer[SO_BUF_LEN_MAX];
					memset( buffer, 0, sizeof(buffer) );

					SERVER_DEBUG( "receive message:\n" );

					ssize_t length = 0;
					if( ( length = read_wrapper(sockfd, buffer, sizeof(buffer)) ) < 0 )
					{
						SERVER_DEBUG( "read error:%s\n", strerror(errno) );
						return -1;			
					}

					SERVER_DEBUG( "read size = %d\n", length );
					if( 0 == length )
					{
						SERVER_DEBUG( "closing socket\n" );
						epollev.data.fd = sockfd;
						if( epoll_ctl( epfd, EPOLL_CTL_DEL, sockfd, &epollev) < 0 )
						{
							SERVER_DEBUG( "epoll_ctl error:%s\n", strerror( errno ) );	
							close( epfd );
							return -1;
						}
						close( sockfd );
					} else {
						SERVER_DEBUG( "buffer:%s\n", buffer );		
						const char* message = get_time_string();
						SERVER_DEBUG( "send message:%s\n", message );
						if( ( length = write_wrapper( sockfd, message, strlen(message) ) ) < 0 )
						{
							SERVER_DEBUG( "write error:%s\n", strerror(errno) );
							return -1;			
						}
						SERVER_DEBUG( "write size = %d\n", length );
					}
				}	
			}	
		}
	}

	return 0;
}
Exemplo n.º 23
0
int 
server( int listen_port, const char* host_ip, int host_port )
{
	#if !defined(HTTP_PROXY) && !defined(SERVER)
	assert( NULL != host_ip );
	#endif
	
	int sockfd = 0;
	if( (sockfd=socket(AF_INET,SOCK_STREAM,0) ) == -1 )
	{
		SERVER_DEBUG( "server socket error:%s\n", strerror(errno) );
		return -1;
	}
	SERVER_DEBUG( "server socket successfully\n" );	

	if( setsockopt_wrapper( sockfd ) < 0 )
	{
		SERVER_DEBUG( "setsockopt_wrapper error:%s\n", strerror(errno) );
		close( sockfd );
		return -1;
	}

	struct sockaddr_in server_addr;	
	memset( &server_addr, 0, sizeof(server_addr) );
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons( listen_port );

	if( bind( sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr) ) == - 1 )
	{
		SERVER_DEBUG( "server bind error:%s\n", strerror(errno) );
		close( sockfd );
		return -1;			
	}
	SERVER_DEBUG( "server bind successfully\n" );	

	if( listen( sockfd, BACK_LOG_DEFAULT ) == -1 )
	{
		SERVER_DEBUG( "server listen error:%s\n", strerror(errno) );
		close( sockfd );
		return -1;			
	}		
	SERVER_DEBUG( "server listen successfully port = %d\n", listen_port );	

	#if defined(EPOLL)
	return epoll_server( sockfd );
	#endif

	parent = getpid();
	
	struct pthread_vargs *list = NULL;

	while(1) 
	{
		if( exit_flag )
		{
			break;
		}
	
		int sockfd_new = handle_new_connection( sockfd );
		if( sockfd_new < 0 )
		{
			SERVER_DEBUG( "handle_new_connection\n" );
			break;
		}

		#if !defined(MULTI_PTHREAD)
		pid_t child = fork();
		if( child < 0 )
		{
			SERVER_DEBUG( "fork error:%s\n", strerror(errno) );
			close( sockfd_new );	
			break;
		}else if( child == 0 ){
			SERVER_DEBUG( "child process\n" );
			close( sockfd );
			#if defined(PROXY)
			if( process_proxy( sockfd_new, host_ip, host_port ) < 0 )
			{
				SERVER_DEBUG( "process_proxy error:%s\n", strerror(errno) );
				close( sockfd_new );	
				break;
			}		
			#elif defined(HTTP_PROXY)
			if( process_http_proxy( sockfd_new ) < 0 )
			{
				SERVER_DEBUG( "process_http_proxy error\n" );
				close( sockfd_new );	
				break;
			}		
			#elif defined(SERVER)
			if( process_server( sockfd_new ) < 0 )
			{
				SERVER_DEBUG( "process_server error:%s\n", strerror(errno) );
				close( sockfd_new );	
				break;
			}		
			#endif
		} else {
			int status;
			SERVER_DEBUG( "waitpid\n" );
			close( sockfd_new );	
			waitpid( -1, &status, WNOHANG );
		}
		#elif defined(MULTI_PTHREAD)
		struct pthread_vargs *pv = (struct pthread_vargs *)malloc(sizeof(struct pthread_vargs));
		if( NULL == pv )
		{
			SERVER_DEBUG( "malloc error:%s\n", strerror(errno) );
			close( sockfd_new );	
			break;
		}
		memset( pv, 0, sizeof(struct pthread_vargs) );
		if( NULL == list )
		{
			list = pv;
			list->next = NULL;
		} else {
			struct pthread_vargs *iter = list;
			while( NULL != iter->next )
			{
				iter = iter->next;
			}
			iter->next = pv;
			pv->next = NULL;
			iter = NULL;
		}
		pv->sockfd = sockfd_new;
		if( pthread_create( &pv->pid, NULL, pthread_http_proxy, pv ) < 0 )
		{
			SERVER_DEBUG( "pthread_create error\n" );
			close( sockfd_new );	
			break;
		}	
		#endif
	}

	#if defined(MULTI_PTHREAD)
	(void)pthread_join_wrapper( list );
	pthread_vargs_cleanup( list );
	#endif

	close( sockfd );
	SERVER_DEBUG( "server close\n" );
	
	return 0;	
}