Example #1
0
handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
	server     *srv = (server *)s;
	server_socket *srv_socket = (server_socket *)context;
	connection *con;
	int loops = 0;

	UNUSED(context);

	if (revents != FDEVENT_IN) {
		log_error_write(srv, __FILE__, __LINE__, "sdd",
				"strange event for server socket",
				srv_socket->fd,
				revents);
		return HANDLER_ERROR;
	}

	/* accept()s at most 100 connections directly
	 *
	 * we jump out after 100 to give the waiting connections a chance */
	for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
		handler_t r;

		connection_state_machine(srv, con);

		switch(r = plugins_call_handle_joblist(srv, con)) {
		case HANDLER_FINISHED:
		case HANDLER_GO_ON:
			break;
		default:
			log_error_write(srv, __FILE__, __LINE__, "d", r);
			break;
		}
	}
	return HANDLER_GO_ON;
}
Example #2
0
static handler_t network_server_handle_fdevent(server *srv, void *context, int revents) {
	server_socket *srv_socket = (server_socket *)context;
	connection *con;
	int loops = 0;

	UNUSED(context);

	if (0 == (revents & FDEVENT_IN)) {
		log_error_write(srv, __FILE__, __LINE__, "sdd",
				"strange event for server socket",
				srv_socket->fd,
				revents);
		return HANDLER_ERROR;
	}

	/* accept()s at most 100 connections directly
	 *
	 * we jump out after 100 to give the waiting connections a chance */
	for (loops = 0; loops < 100 && NULL != (con = connection_accept(srv, srv_socket)); loops++) {
		connection_state_machine(srv, con);
	}
	return HANDLER_GO_ON;
}
//处理监听套接字的可读(register时指定用该函数)
handler_t network_server_handle_fdevent(void *s, void *context, int revents) {
	server     *srv = (server *)s;
	server_socket *srv_socket = (server_socket *)context;
	connection *con;
	int loops = 0;
	UNUSED(context);
	/*
		首先要判断传入的event事件是否是FDEVENT_IN,也就是说,只可能在fd有可读数据的时候才触发该函数,其他的情况都错误。
	*/
	if (revents != FDEVENT_IN) {
		log_error_write(srv, __FILE__, __LINE__, "sdd",
				"strange event for server socket",
				srv_socket->fd,
				revents);
		return HANDLER_ERROR;
	}

	 /*
		接收客户端连接请求,每个监听套接口描述符一次接收请求数目最大为100,使得各监听套接口上的连接请求都得到及时处理。
	 */
//connection_accept()函数用来完成连接套接口描述符的创建		
	for (loops = 0; loops < 100 && NULL != (con=connection_accept(srv, srv_socket)); loops++) { 
		handler_t r;

//connection_state_machine()函数(连接状态转换管理器)和plugins_call_handle_joblist()函数用于对请求连接进行处理。
		connection_state_machine(srv, con); 
		switch(r = plugins_call_handle_joblist(srv, con)) {
		case HANDLER_FINISHED:
		case HANDLER_GO_ON:
			break;
		default:
			log_error_write(srv, __FILE__, __LINE__, "d", r);
			break;
		}
	}
	return HANDLER_GO_ON;
}
Example #4
0
int main(void)
{
    int server;

    video_init();
    wifi_init();
    while (!wifi_connect());
    server = wifi_listen();

    while (1) {
	static Connection conn;
	int i;
	uint32 data_goal;
	
	connection_accept(&conn, server);

	conn.card_type = cardmeGetType();
	iprintf("Card type %d\n", conn.card_type);
	if (conn.card_type <= 0) {
	    close(conn.fd);
	    continue;
	}

	conn.card_size = cardmeSize(conn.card_type);
	iprintf("%d byte EEPROM\n", conn.card_size);

	for (conn.address = 0;
	     conn.address < conn.card_size;
	     conn.address += sizeof conn.buffer) {
	    int sent = 0;

	    cardmeReadEeprom(conn.address, conn.buffer, sizeof conn.buffer, conn.card_type);

	    data_goal = Wifi_GetStats(WSTAT_TXDATABYTES) + sizeof conn.buffer;

	    do {
		sent += send(conn.fd, conn.buffer + sent, sizeof conn.buffer - sent, 0);
	    } while (sent < sizeof conn.buffer);

	    /*
	     * dswifi's TCP stack is buggy... or sometihing. It's retransmitting every packet
	     * several times. This seems to help a little. Also, this should help work around
	     * the fact that dswifi doesn't flush any buffers on close().
	     */	   
	    while (Wifi_GetStats(WSTAT_TXDATABYTES) < data_goal) {
		swiWaitForVBlank();
	    }

	    iprintf("(%d bytes)\x1b[60D", conn.address);
	}	
	iprintf("Complete.        \n");

	/*
	 * Wait for the other end to close the connection.
	 * Closing it immediately seems to just lose data in
	 * dswifi's buffers...
	 */
	while (recv(conn.fd, conn.buffer, sizeof conn.buffer, 0) > 0);
	close(conn.fd);
    }

    return 0;
}
Example #5
0
int main(int argc, char *argv[])
{
	time_t t;
	struct tm *tm;
	fd_set master;
	fd_set read_fds;
	int fdmax, i, j=0, k=0;
	int sockfd=0;
	char *cad = malloc(BUFSIZE);
	struct sockaddr_in my_addr, client_addr;

 	bind_textdomain_codeset ("fuentes", "UTF-8");
        setlocale(LC_ALL, "");
        bindtextdomain("fuentes", "idioma");
        textdomain("fuentes");


	if(argc==2)
	{
		CONEXIONES clientes[MAX_CONN];
	
		FD_ZERO(&master);
		FD_ZERO(&read_fds);
		connect_request(&sockfd, &my_addr, atoi(argv[1]));
		FD_SET(sockfd, &master);
	
		t = time(NULL);
		tm=localtime(&t); 

		fdmax = sockfd;
		while(1){
			read_fds = master;
			if(select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1){
				perror(_("Seleccionar"));
				exit(4);
			}
		
			for (i = 0; i <= fdmax; i++){
				if (FD_ISSET(i, &read_fds)){
					if (i == sockfd)	
					{							
						clientes[j].fds=connection_accept(&master, &fdmax, sockfd, &client_addr);
						clientes[j].dir = client_addr.sin_addr;
						clientes[j].hora = tm->tm_hour;
						clientes[j].min = tm->tm_min;
						clientes[j].seg = tm->tm_sec;
						j++;					
					}
					else
					{
						for(k=0;k<j;k++)
						{
							if(clientes[k].fds == i)
							{
								sprintf(cad, "[%s]-Dice: ",inet_ntoa(clientes[k].dir));
								send_recv(i, &master, sockfd, fdmax, cad);
							}

						}					
					}
				}
			}
		}	
	return 0;
	}
	else	
	{
		printf(_("Número de argumentos invalido\n"));
		return -1;
	}
}
void server_wait(server *s)
{
	int maxfd = s->socket;
	fd_set rfds;
	FD_ZERO(&rfds);
	FD_SET(s->socket, &rfds);

	GList *i;
	for (i = s->connections; i != NULL; i = i->next)
	{
		connection *c = (connection *)i->data;
		int fd = connection_socket(c);
		if (fd > maxfd) maxfd = fd;
		FD_SET(fd, &rfds);
	}

	struct timeval tv;
	tv.tv_sec = TIMEOUT_SEC;
	tv.tv_usec = TIMEOUT_USEC;
	int status = select(maxfd + 1, &rfds, NULL, NULL, &tv);

	if (status > 0)
	{
		if (FD_ISSET(s->socket, &rfds))
		{
			if (!g_queue_is_empty(s->free_connections))
			{
				connection *c = (connection *)g_queue_pop_head(s->free_connections);
				s->connections = g_list_append(s->connections, c);

				connection_accept(c, s->socket);
				if (connection_socket(c) == 0) halt_error("Socket accept really shouldn't fail");
			}
		}

		GList *j = s->connections;
		while (j != NULL)
		{
			GList *next = j->next;

			connection *c = (connection *)j->data;
			if (FD_ISSET(connection_socket(c), &rfds))
			{
				if (connection_receive(c))
				{
					j->data = NULL;
					s->connections = g_list_delete_link(s->connections, j);
					g_queue_push_tail(s->free_connections, c);
				}
			}

			j = next;
		}
	}
	else if (status == 0)
	{
		// connection timeout
		GList *j = s->connections;
		while (j != NULL)
		{
			GList *next = j->next;

			connection *c = (connection *)j->data;
			connection_timeout_increment(c, TIMEOUT_SEC + (((float)TIMEOUT_USEC) / 1000000.0f));

			if (connection_timedout(c))
			{
				j->data = NULL;
				s->connections = g_list_delete_link(s->connections, j);
				g_queue_push_tail(s->free_connections, c);
			}

			j = next;
		}
	}
	else
	{
		// TODO: Don't know if this is ever a fatal error
		//halt_error("Error in socket select");
		return;
	}
}
Example #7
0
int main(int argc, char **argv) {
  int opt;
  char *user =0;
  char *host;
  unsigned long port;
  int pid;
  int s;
  int conn;
  int delim;

  progname =*argv;
  phccmax =0;

#ifdef SSLSVD
  while ((opt =getopt(argc, (const char **)argv,
                      "c:C:i:x:u:l:Eb:hpt:vVU:/:Z:K:")) != opteof) {
#else
  while ((opt =getopt(argc, (const char **)argv,
                      "c:C:i:x:u:l:Eb:hpt:vV")) != opteof) {
#endif
    switch(opt) {
    case 'c': scan_ulong(optarg, &cmax); if (cmax < 1) usage(); break;
    case 'C':
      delim =scan_ulong(optarg, &phccmax);
      if (phccmax < 1) usage();
      if (optarg[delim] == ':') {
        if (ipsvd_fmt_msg(&msg, optarg +delim +1) == -1) die_nomem();
        if (! stralloc_0(&msg)) die_nomem();
        phccmsg =msg.s;
      }
      break;
    case 'i': if (instructs) usage(); instructs =optarg; break;
    case 'x': if (instructs) usage(); instructs =optarg; iscdb =1; break;
    case 'u': user =(char*)optarg; break;
    case 'l':
      if (! stralloc_copys(&local_hostname, optarg)) die_nomem();
      if (! stralloc_0(&local_hostname)) die_nomem();
      break;
    case 'E': ucspi =0; break;
    case 'b': scan_ulong(optarg, &backlog); break;
    case 'h': lookuphost =1; break;
    case 'p': lookuphost =1; paranoid =1; break;
    case 't': scan_ulong(optarg, &timeout); break;
    case 'v': ++verbose; break;
#ifdef SSLSVD
    case 'U': ssluser =(char*)optarg; break;
    case '/': root =(char*)optarg; break;
    case 'Z': cert =(char*)optarg; break;
    case 'K': key =(char*)optarg; break;
#endif
    case 'V': strerr_warn1(VERSION, 0);
    case '?': usage();
    }
  }
  argv +=optind;

  if (! argv || ! *argv) usage();
  host =*argv++;
  if (! argv || ! *argv) usage();
  local_port =*argv++;
  if (! argv || ! *argv) usage();
  prog =(const char **)argv;
  if (phccmax > cmax) phccmax =cmax;

  if (user)
    if (! uidgids_get(&ugid, user)) {
      if (errno)
        strerr_die4sys(111, FATAL, "unable to get user/group: ", user, ": ");
      strerr_die3x(100, FATAL, "unknown user/group: ", user);
    }
#ifdef SSLSVD
  svuser =user;
  client =0;
  if ((getuid() == 0) && (! ssluser))
    strerr_die2x(100, FATAL, "-U ssluser must be set when running as root");
  if (ssluser)
    if (! uidgids_get(&sslugid, ssluser)) {
      if (errno)
        strerr_die4sys(111, FATAL, "unable to get user/group: ", ssluser, ": ");
      strerr_die3x(100, FATAL, "unknown user/group: ", ssluser);
    }
  if (! cert) cert ="./cert.pem";
  if (! key) key =cert;
  if (matrixSslOpen() < 0) fatal("unable to initialize ssl");
  if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) {
    if (client) fatal("unable to read cert, key, or ca file");
    fatal("unable to read cert or key file");
  }
  if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0)
    strerr_die2x(111, FATAL, "unable to create ssl session");
#endif

  dns_random_init(seed);
  sig_block(sig_child);
  sig_catch(sig_child, sig_child_handler);
  sig_catch(sig_term, sig_term_handler);
  sig_ignore(sig_pipe);

  if (phccmax) if (ipsvd_phcc_init(cmax) == -1) die_nomem();

  if (str_equal(host, "")) host ="0.0.0.0";
  if (str_equal(host, "0")) host ="0.0.0.0";

  if (! ipsvd_scan_port(local_port, "tcp", &port))
    strerr_die3x(100, FATAL, "unknown port number or name: ", local_port);

  if (! stralloc_copys(&sa, host)) die_nomem();
  if ((dns_ip4(&ips, &sa) == -1) || (ips.len < 4))
    if (dns_ip4_qualify(&ips, &fqdn, &sa) == -1)
      fatal2("unable to look up ip address", host);
  if (ips.len < 4)
    strerr_die3x(100, FATAL, "unable to look up ip address: ", host);
  ips.len =4;
  if (! stralloc_0(&ips)) die_nomem();
  local_ip[ipsvd_fmt_ip(local_ip, ips.s)] =0;

  if (! lookuphost) {
    if (! stralloc_copys(&remote_hostname, "")) die_nomem();
    if (! stralloc_0(&remote_hostname)) die_nomem();
  }

  if ((s =socket_tcp()) == -1) fatal("unable to create socket");
  if (socket_bind4_reuse(s, ips.s, port) == -1)
    fatal("unable to bind socket");
  if (listen(s, backlog) == -1) fatal("unable to listen");
  ndelay_off(s);

#ifdef SSLSVD
#else
  if (user) {
    /* drop permissions */
    if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to set groups");
    if (setgid(*ugid.gid) == -1) fatal("unable to set gid");
    if (prot_uid(ugid.uid) == -1) fatal("unable to set uid");
  }
#endif
  close(0);

  if (verbose) {
    out(INFO); out("listening on "); outfix(local_ip); out(":");
    outfix(local_port);
#ifdef SSLSVD
#else
    if (user) {
      bufnum[fmt_ulong(bufnum, (unsigned long)ugid.uid)] =0;
      out(", uid "); out(bufnum);
      bufnum[fmt_ulong(bufnum, (unsigned long)ugid.gid)] =0;
      out(", gid "); out(bufnum);
    }
#endif
    flush(", starting.\n");
  }
  for (;;) {
    while (cnum >= cmax) sig_pause();
    socka_size =sizeof(socka);

    sig_unblock(sig_child);
    conn =accept(s, (struct sockaddr *)&socka, &socka_size);
    sig_block(sig_child);

    if (conn == -1) {
      if (errno != error_intr) warn("unable to accept connection");
      continue;
    }
    cnum++;

    if (verbose) connection_status();
    if (phccmax) phcc =ipsvd_phcc_add((char*)&socka.sin_addr);
    if ((pid =fork()) == -1) {
      warn2("drop connection", "unable to fork");
      close(conn);
      continue;
    }
    if (pid == 0) {
      /* child */
      close(s);
#ifdef SSLSVD
      if (*progname) *progname ='\\';
#endif
      connection_accept(conn);
    }
    if (phccmax) ipsvd_phcc_setpid(pid);
    close(conn);
  }
  _exit(0);
}
Example #8
0
int server(unsigned short port, int demarcaciones, int taxPorDemarcacion, int iters, int timeout_millis, int txdelay_millis, bool debug) {
	connection_t conn;
	packet_t outgoing;
	packet_t * incoming;

	if (!connection_server(&conn, port)) {
		fprintf(stderr, "Unable to spawn server on port %u: ", port);
		connection_error(&conn, stderr);
		fprintf(stderr, "\n");
		return 1;
	}

	if (debug) {
		connection_debug(&conn, stderr);
	}

	gestion_taxi_t * taxis = calloc(demarcaciones * taxPorDemarcacion, sizeof(gestion_taxi_t));
	if (taxis == NULL) {
		fprintf(stderr, "Failed to allocate memory for taxi stats structure: %s\n", strerror(errno));
		return 1;
	}

	fprintf(stderr, "Waiting for clientes at port: [%d]\n", port);
	int connected = 0;
	int pendingAccAck = demarcaciones * taxPorDemarcacion;
	while (pendingAccAck > 0) {
		if (!connection_receive(&conn, &incoming, NULL)) { /* TODO: check how to safely implement a timeout here */
			fprintf(stderr, "Error receiving login packet: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");

			if (connection_dead(&conn)) {
				connection_close(&conn);
				free(taxis);
				return 1;
			}

			continue;
		}

		bool duplicate = false;
		int pos;
		switch (incoming->type) {
			case PACKET_TYPE_LOGIN:
				if (incoming->login.version != PACKET_VERSION) {
					fprintf(stderr, "Got LOGIN with version %08X but server version is %08X\n", incoming->login.version, PACKET_VERSION);
					connection_discard(&conn);
					continue;
				}
				connection_accept(&conn);

				for (pos = 0; pos < connected; pos++) {
					if (connection_cmp(&taxis[pos].conexionConTaxi, &conn)) {
						duplicate = true;
						fprintf(stderr, "Got duplicated login packet from taxi %d-%d. Re-sending acknowledgement\n", pos / taxPorDemarcacion, pos % taxPorDemarcacion);
						break;
					}
				}

				if (!duplicate) {
					if (connected == taxPorDemarcacion * demarcaciones) {
						fprintf(stderr, "Received new LOGIN but all taxis have been already registered\n");
						continue;
					}

					fprintf(stderr, "Registered new taxi %d-%d\n", connected / taxPorDemarcacion, connected % taxPorDemarcacion);
					memcpy(&taxis[connected].conexionConTaxi, &conn, sizeof(conn));
					connected++;
				}

				outgoing.type = PACKET_TYPE_ACCEPT;
				outgoing.accept.zone = pos / taxPorDemarcacion;
				outgoing.accept.id = pos % taxPorDemarcacion;
				outgoing.accept.neighbors = taxPorDemarcacion - 1;
				outgoing.accept.ticks = iters;
				outgoing.accept.timeout = timeout_millis;
				outgoing.accept.txdelay = txdelay_millis;
				if (!connection_send(&conn, &outgoing)) {
					fprintf(stderr, "Error replying to login packet: ");
					connection_error(&conn, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}

				break;

			case PACKET_TYPE_ACCACK:
				if (incoming->accack.zone >= demarcaciones || incoming->accack.id >= taxPorDemarcacion) {
					fprintf(stderr, "Received illegal accept acknowledgement from taxi %u-%u\n", incoming->accack.zone, incoming->accack.id);
					connection_discard(&conn);
					continue;
				}
				connection_accept(&conn);

				gestion_taxi_t * taxi = &taxis[incoming->accack.zone * taxPorDemarcacion + incoming->accack.id];
				if (!taxi->hasAckdAccept) {
					taxi->hasAckdAccept = true;
					pendingAccAck--;
				}
				break;

			default:
				connection_discard(&conn);
				fprintf(stderr, "Unexpected packet %s during login phase. Discarding.\n", packet_name(incoming));
				continue;
		}
	}

	outgoing.type = PACKET_TYPE_START;
	for (int pos = 0; pos < demarcaciones * taxPorDemarcacion; pos++) {
		if (!connection_send(&taxis[pos].conexionConTaxi, &outgoing)) {
			fprintf(stderr, "Error sending start packet: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");
			connection_close(&conn);
			free(taxis);
			return 1;
		}
	}

	int statsRcv = 0;
	struct timeval defaulttimeout = { (timeout_millis * 2) / 1000, ((timeout_millis * 2) % 1000) * 1000 };
	struct timeval timeout = defaulttimeout;
	while (statsRcv < demarcaciones * taxPorDemarcacion) {
		if (!connection_receive(&conn, &incoming, NULL)) {
			fprintf(stderr, "Error receiving packet in main loop: ");
			connection_error(&conn, stderr);
			fprintf(stderr, "\n");

			if (conn.err == CONNERR_TIMEOUT) {
				break;
			}

			if (connection_dead(&conn)) {
				connection_close(&conn);
				free(taxis);
				return 1;
			}

			continue;
		}

		gestion_taxi_t * taxi;
		switch (incoming->type) {
			case PACKET_TYPE_ACCACK:
				outgoing.type = PACKET_TYPE_START;
				if (!connection_send(&conn, &outgoing)) {
					fprintf(stderr, "Failed to send start packet in main loop: ");
					connection_error(&conn, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					return 1;
				}
				timeout = defaulttimeout;
				break;

			case PACKET_TYPE_POSITION:
				if (incoming->position.zone > demarcaciones || incoming->position.id > taxPorDemarcacion) {
					fprintf(stderr, "Received position from illegal taxi %u-%u\n", outgoing.position.zone, outgoing.position.id);
					connection_discard(&conn);
					continue;
				}

				for (int neighbor = 0; neighbor < taxPorDemarcacion; neighbor++) {
					if (neighbor == incoming->position.id) {
						continue;
					}

					if (!connection_send(&taxis[incoming->position.zone * taxPorDemarcacion + neighbor].conexionConTaxi, incoming)) {
						fprintf(stderr, "Error forwarding position packet: ");
						connection_error(&taxis[incoming->position.zone * taxPorDemarcacion + neighbor].conexionConTaxi, stderr);
						fprintf(stderr, "\n");
						connection_close(&conn);
						free(taxis);
						return 1;
					}
				}
				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			case PACKET_TYPE_POSACK:
				if (incoming->posack.zone > demarcaciones || incoming->posack.id > taxPorDemarcacion) {
					fprintf(stderr, "Received acknowledgement from illegal taxi %u-%u\n", incoming->posack.zone, incoming->posack.id);
					break;
				}

				if (incoming->posack.neighbor > taxPorDemarcacion) {
					fprintf(stderr, "Received acknowledgement from %u-%u targeting out-of-bounds taxi %u-%u\n", incoming->posack.zone, incoming->posack.id, incoming->posack.zone, incoming->posack.neighbor);
					break;
				}

				taxi = &taxis[incoming->posack.zone * taxPorDemarcacion + incoming->posack.neighbor];
				if (!connection_send(&taxi->conexionConTaxi, incoming)) {
					fprintf(stderr, "Error forwarding acknowledgement packet: ");
					connection_error(&taxi->conexionConTaxi, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}
				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			case PACKET_TYPE_STATS:
				taxi = &taxis[incoming->stats.zone * taxPorDemarcacion + incoming->stats.id];
				if (!taxi->hasSentStats) {
					printf("%u, %u, %u, %u, %u, %u, %u, %u\n",
						incoming->stats.zone,
						incoming->stats.id,
						incoming->stats.ticks,
						incoming->stats.posrcv,
						incoming->stats.ackrcv,
						incoming->stats.itmin,
						incoming->stats.itavg,
						incoming->stats.itmax
					);
					taxi->hasSentStats = true;
					statsRcv++;
				}

				outgoing.type = PACKET_TYPE_STATACK;
				if (!connection_send(&taxi->conexionConTaxi, &outgoing)) {
					fprintf(stderr, "Error sending stats acknowledgement packet: ");
					connection_error(&taxi->conexionConTaxi, stderr);
					fprintf(stderr, "\n");
					connection_close(&conn);
					free(taxis);
					return 1;
				}

				timeout = defaulttimeout;
				connection_accept(&conn);
				break;

			default:
				fprintf(stderr, "Unexpected packet %s during main loop\n", packet_name(incoming));
				connection_discard(&conn);
				continue;
		}
	}

	// TODO: Interpretar estadísticas
	return 0;
}