Пример #1
0
bool
Harness::SendMessage (const char *msg, guint8 **buffer, guint32 *output_length)
{
	char *tmp;
	int sockfd;
	int result;
	sockaddr_in addr;
	char *strport;
	int port;
	sockaddr_in peer;
	socklen_t peer_length = sizeof (peer);

	*output_length = 0;
	*buffer = NULL;

	// get and validate port
	strport = getenv ("MOONLIGHT_HARNESS_LISTENER_PORT");
	if (strport == NULL || strport [0] == 0) {
		printf ("[%i shocker]: MOONLIGHT_HARNESS_LISTENER_PORT is not set, assuming a default value of 1234\n", getpid ());
		port = 1234;
	} else {
		port = atoi (strport);
		if (port < 1024) {
			printf ("[%i shocker]: The port MOONLIGHT_HARNESS_LISTENER_PORT (%s) is probably invalid, it should be >= 1024.\n", getpid (), strport);
		}
	}

	// create the socket
	sockfd = socket (PF_INET, SOCK_STREAM, 0);

	if (sockfd == -1) {
		printf ("[%i shocker]: Failed to open socket: %i (%s)\n", getpid (), errno, strerror (errno));
		return false;
	}

	// connect
	addr.sin_family = AF_INET;
	addr.sin_port = htons (port);
	memset (addr.sin_zero, 0, sizeof (addr.sin_zero));
	result = inet_pton (AF_INET, "127.0.0.1", &addr.sin_addr);
	result = connect (sockfd, (struct sockaddr *) &addr, sizeof (addr));

	if (result == -1) {
		printf ("[%i shocker]: Could not connect to localhost:%i (%i %s)\n", getpid (), port, errno, strerror (errno));
		goto cleanup;
	} 

	result = getsockname (sockfd, (struct sockaddr *) &peer, &peer_length);
	LOG_HARNESS ("[%i shocker]: Connected to port %i\n", getpid (), ntohs (peer.sin_port));

	// send request
	tmp = g_strdup_printf ("v2|%s", msg);
	if (!send_all (sockfd, tmp, strlen (tmp))) {
		g_free (tmp);
		result = -1;
		goto cleanup;
	}
	g_free (tmp);

	// First 4 bytes is the size
	if (!recv_all (sockfd, (guint8 *) output_length, 4)) {
		result = -1;
		goto cleanup;
	}

	LOG_HARNESS ("[%i shocker]: receiving %i bytes...\n", getpid (), *output_length);

	// Then the response
	*buffer = (guint8 *) g_malloc0 (*output_length + 1 /* any missing null terminator */);
	if (!recv_all (sockfd, *buffer, *output_length)) {
		g_free (*buffer);
		*buffer = NULL;
		result = -1;
		goto cleanup;
	}

	LOG_HARNESS ("[%i shocker]: received %i bytes from port %i\n", getpid (), *output_length, ntohs (peer.sin_port));

cleanup:
	close (sockfd);

	return result != -1;
}
Пример #2
0
/*! \brief Finds a tcpconn & sends on it */
int tcp_send(struct socket_info* send_sock, int type, char* buf, unsigned len,
			union sockaddr_union* to, int id)
{
	struct tcp_connection *c;
	struct tcp_connection *tmp;
	struct ip_addr ip;
	int port;
	int fd;
	long response[2];
	int n;
	struct timeval get,rcv,snd;
	
	port=0;

	reset_tcp_vars(tcpthreshold);
	start_expire_timer(get,tcpthreshold);

	if (to){
		su2ip_addr(&ip, to);
		port=su_getport(to);
		c=tcpconn_get(id, &ip, port, tcp_con_lifetime); 
	}else if (id){
		c=tcpconn_get(id, 0, 0, tcp_con_lifetime);
	}else{
		LM_CRIT("tcp_send called with null id & to\n");
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
		return -1;
	}
	
	if (id){
		if (c==0) {
			if (to){
				/* try again w/o id */
				c=tcpconn_get(0, &ip, port, tcp_con_lifetime);
				goto no_id;
			}else{
				LM_ERR("id %d not found, dropping\n", id);
				get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
				return -1;
			}
		}else goto get_fd;
	}
no_id:
		if (c==0){
			LM_DBG("no open tcp connection found, opening new one\n");
			/* create tcp connection */
			if ((c=tcpconn_connect(send_sock, to, type))==0){
				LM_ERR("connect failed\n");
				get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
				return -1;
			}
			c->refcnt++; /* safe to do it w/o locking, it's not yet
							available to the rest of the world */
			fd=c->s;
			
			/* send the new tcpconn to "tcp main" */
			response[0]=(long)c;
			response[1]=CONN_NEW;
			n=send_fd(unix_tcp_sock, response, sizeof(response), c->s);
			get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
			if (n<=0){
				LM_ERR("failed send_fd: %s (%d)\n",	strerror(errno), errno);
				n=-1;
				goto end;
			}	
			goto send_it;
		}
get_fd:
		get_time_difference(get,tcpthreshold,tcp_timeout_con_get);
			/* todo: see if this is not the same process holding
			 *  c  and if so send directly on c->fd */
			LM_DBG("tcp connection found (%p), acquiring fd\n", c);
			/* get the fd */
			response[0]=(long)c;
			response[1]=CONN_GET_FD;
			start_expire_timer(rcv,tcpthreshold);
			n=send_all(unix_tcp_sock, response, sizeof(response));
			if (n<=0){
				LM_ERR("failed to get fd(write):%s (%d)\n",	
						strerror(errno), errno);
				n=-1;
				get_time_difference(rcv,tcpthreshold,tcp_timeout_receive_fd);
				goto release_c;
			}
			LM_DBG("c= %p, n=%d\n", c, n);
			tmp=c;
			n=receive_fd(unix_tcp_sock, &c, sizeof(c), &fd, MSG_WAITALL);
			get_time_difference(rcv,tcpthreshold,tcp_timeout_receive_fd);
			if (n<=0){
				LM_ERR("failed to get fd(receive_fd):"
							" %s (%d)\n", strerror(errno), errno);
				n=-1;
				goto release_c;
			}
			if (c!=tmp){
				LM_CRIT("got different connection:"
						"  %p (id= %d, refcnt=%d state=%d != "
						"  %p (id= %d, refcnt=%d state=%d (n=%d)\n",
						  c,   c->id,   c->refcnt,   c->state,
						  tmp, tmp->id, tmp->refcnt, tmp->state, n
				   );
				n=-1; /* fail */
				goto end;
			}
			LM_DBG("after receive_fd: c= %p n=%d fd=%d\n",c, n, fd);
		
	
	
send_it:
	LM_DBG("sending...\n");
	lock_get(&c->write_lock);
#ifdef USE_TLS
	if (c->type==PROTO_TLS)
		n=tls_blocking_write(c, fd, buf, len);
	else
#endif
		/* n=tcp_blocking_write(c, fd, buf, len); */
		start_expire_timer(snd,tcpthreshold);
		n=tsend_stream(fd, buf, len, tcp_send_timeout*1000); 
		get_time_difference(snd,tcpthreshold,tcp_timeout_send);
	
		stop_expire_timer(get,tcpthreshold,0,buf,(int)len,1);
	lock_release(&c->write_lock);
	LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd);
	LM_DBG("buf=\n%.*s\n", (int)len, buf);
	if (n<0){
		LM_ERR("failed to send\n");
		/* error on the connection , mark it as bad and set 0 timeout */
		c->state=S_CONN_BAD;
		c->timeout=0;
		/* tell "main" it should drop this (optional it will t/o anyway?)*/
		response[0]=(long)c;
		response[1]=CONN_ERROR;
		n=send_all(unix_tcp_sock, response, sizeof(response));
		/* CONN_ERROR will auto-dec refcnt => we must not call tcpconn_put !!*/
		if (n<=0){
			LM_ERR("return failed (write):%s (%d)\n",
					strerror(errno), errno);
		}
		close(fd);
		return -1; /* error return, no tcpconn_put */
	}
end:
	close(fd);
release_c:
	tcpconn_put(c); /* release c (lock; dec refcnt; unlock) */
	return n;
}
Пример #3
0
void do_command(char *msg, Client *client)
{
	char *command,*p;
	int len;

	if(!msg || !strlen(msg) || !client)
		return;
	len=strlen(msg);
	p=msg;
	command=strsep(&p," \t");
	/* /NICK : change the clients name */
	if(!strcasecmp(command,"NICK"))
	{
		if(p && strlen(p))
		{
			char *old_name=client->name;

			fix_nick(p);
			if(!strlen(p))
			{
				putMsg(client->sock,"--- Invalid Nickname!");
				return;
			}
			if(!unique_nick(p))
			{
				putMsg(client->sock,"--- Duplicate Nickname!");
				return;
			}
			client->name=strdup(p);
			send_all(mformat("ssss","--- ",old_name," --> ",p));
			free(old_name);
		}
		else
			putMsg(client->sock,"--- /NICK nickname");
		return;
	}
	/* MSG : client to client message */
	if(!strcasecmp(command,"MSG"))
	{
		char *name;
		int to;

		if(p)
		{
			name=strsep(&p," ");
			to=find_client_name(name);
			if(to<0)
			{
				putMsg(client->sock, mformat("sss","--- /MSG nickname ",name," not found!"));
				return;
			}
			else if(p && strlen(p))
			{
				putMsg(client->sock,mformat("ssss",">",clients[to].name,"< ",p));
				putMsg(clients[to].sock,mformat("ssss",">",client->name,"< ",p));
				return;
			}
		}
		putMsg(client->sock,"--- /MSG nickname message...");
		return;
	}
	/* /ME : emote! to everyone */
	if(!strcasecmp(command,"ME"))
	{
		if(p && strlen(p))
		{
			send_all(mformat("sss",client->name," ",p));
		}
		else
			putMsg(client->sock,"--- /ME message...");
		return;
	}
	/* /QUIT : quit the server with a message */
	if(!strcasecmp(command,"QUIT"))
	{
		if(!p || strcasecmp(p,"-h"))
		{
			if(p)
				send_all(mformat("ssss","--- ",client->name," quits : ",p));
			else
				send_all(mformat("sss","--- ",client->name," quits"));
			remove_client(find_client(client->sock));
		}
		else
			putMsg(client->sock,"--- /QUIT [message...]");
		return;
	}
	/* /WHO : list the users online back to the client */
	if(!strcasecmp(command,"WHO"))
	{
		int i;
		IPaddress *ipaddr;
		Uint32 ip;
		const char *host=NULL;

		putMsg(client->sock,"--- Begin /WHO ");
		for(i=0;i<num_clients;i++)
		{
			ipaddr=SDLNet_TCP_GetPeerAddress(clients[i].sock);
			if(ipaddr)
			{
				ip=SDL_SwapBE32(ipaddr->host);
				host=SDLNet_ResolveIP(ipaddr);
				putMsg(client->sock,mformat("sssssdsdsdsdsd","--- ",clients[i].name,
						" ",host?host:"",
						"[",ip>>24,".", (ip>>16)&0xff,".", (ip>>8)&0xff,".", ip&0xff,
						"] port ",(Uint32)ipaddr->port));
			}
		}
		putMsg(client->sock,"--- End /WHO");
		return;
	}
Пример #4
0
static bool netplay_cmd_nak(netplay_t *handle)
{
   uint32_t cmd = htonl(NETPLAY_CMD_NAK);
   return send_all(handle->fd, &cmd, sizeof(cmd));
}
Пример #5
0
/*! \brief _tcpconn_find with locks and acquire fd */
int tcp_conn_get(int id, struct ip_addr* ip, int port, enum sip_protos proto,
									struct tcp_connection** conn, int* conn_fd)
{
	struct tcp_connection* c;
	struct tcp_connection* tmp;
	struct tcp_conn_alias* a;
	unsigned hash;
	long response[2];
	int part;
	int n;
	int fd;

	if (id) {
		part = id;
		TCPCONN_LOCK(part);
		if ( (c=_tcpconn_find(part))!=NULL )
			goto found;
		TCPCONN_UNLOCK(part);
	}

	/* continue search based on IP address + port + transport */
#ifdef EXTRA_DEBUG
	LM_DBG("%d  port %d\n",id, port);
	if (ip) print_ip("tcpconn_find: ip ", ip, "\n");
#endif
	if (ip){
		hash=tcp_addr_hash(ip, port);
		for( part=0 ; part<TCP_PARTITION_SIZE ; part++ ) {
			TCPCONN_LOCK(part);
			for (a=TCP_PART(part).tcpconn_aliases_hash[hash]; a; a=a->next) {
#ifdef EXTRA_DEBUG
				LM_DBG("a=%p, c=%p, c->id=%d, alias port= %d port=%d\n",
					a, a->parent, a->parent->id, a->port,
					a->parent->rcv.src_port);
				print_ip("ip=",&a->parent->rcv.src_ip,"\n");
#endif
				c = a->parent;
				if (c->state != S_CONN_BAD &&
				    port == a->port &&
				    proto == c->type &&
				    ip_addr_cmp(ip, &c->rcv.src_ip))
					goto found;
			}
			TCPCONN_UNLOCK(part);
		}
	}

	/* not found */
	*conn = NULL;
	if (conn_fd) *conn_fd = -1;
	return 0;

found:
	c->refcnt++;
	TCPCONN_UNLOCK(part);

	LM_DBG("con found in state %d\n",c->state);

	if (c->state!=S_CONN_OK || conn_fd==NULL) {
		/* no need to acquired, just return the conn with an invalid fd */
		*conn = c;
		if (conn_fd) *conn_fd = -1;
		return 1;
	}

	if (c->proc_id == process_no) {
		LM_DBG("tcp connection found (%p) already in this process ( %d ) , fd = %d\n", c, c->proc_id, c->fd);
		/* we already have the connection in this worker's reactor, no need to acquire FD */
		*conn = c;
		*conn_fd = c->fd;
		return 1;
	}

	/* acquire the fd for this connection too */
	LM_DBG("tcp connection found (%p), acquiring fd\n", c);
	/* get the fd */
	response[0]=(long)c;
	response[1]=CONN_GET_FD;
	n=send_all(unix_tcp_sock, response, sizeof(response));
	if (n<=0){
		LM_ERR("failed to get fd(write):%s (%d)\n",
				strerror(errno), errno);
		n=-1;
		goto error;
	}
	LM_DBG("c= %p, n=%d, Usock=%d\n", c, n, unix_tcp_sock);
	tmp = c;
	n=receive_fd(unix_tcp_sock, &c, sizeof(c), &fd, MSG_WAITALL);
	if (n<=0){
		LM_ERR("failed to get fd(receive_fd):"
			" %s (%d)\n", strerror(errno), errno);
		n=-1;
		goto error;
	}
	if (c!=tmp){
		LM_CRIT("got different connection:"
			"  %p (id= %d, refcnt=%d state=%d != "
			"  %p (id= %d, refcnt=%d state=%d (n=%d)\n",
			  c,   c->id,   c->refcnt,   c->state,
			  tmp, tmp->id, tmp->refcnt, tmp->state, n
		   );
		n=-1; /* fail */
		close(fd);
		goto error;
	}
	LM_DBG("after receive_fd: c= %p n=%d fd=%d\n",c, n, fd);

	*conn = c;
	*conn_fd = fd;

	return 1;
error:
	tcpconn_put(c);
	*conn = NULL;
	*conn_fd = -1;
	return -1;
}
static int local_server()
{
	int len;
	int totalSize;
	char buffer[4096];
	HANDLE hFile = INVALID_HANDLE_VALUE;

	serverSk = create_server();
	if (serverSk == INVALID_SOCKET)
		return SOCKET_ERROR;

	while (1) {
		peerSk = accept(serverSk, NULL, NULL);
		if (peerSk == INVALID_SOCKET) {
			continue;
		}

		len = recv(peerSk, buffer, sizeof(buffer), 0);
		if (len <= 0)
			goto closepeer;

		hFile = CreateFile(stage2file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if (hFile == INVALID_HANDLE_VALUE)
			break;

		totalSize = GetFileSize(hFile, NULL);
		if (totalSize == INVALID_FILE_SIZE)
			break;

		len = _snprintf(buffer, sizeof(buffer), 
			"HTTP/1.1 200 OK\r\n"
			"Content-Type: text/html\r\n"
			"Connection: Close\r\n"
			"Content-Length: %d\r\n"
			"\r\n",
			totalSize
		);
		send_all(peerSk, buffer, len);

		while (totalSize > 0) {
			ReadFile(hFile, buffer, sizeof(buffer), (DWORD*) &len, NULL);
			send_all(peerSk, buffer, len);
			totalSize -= len;
		}
		CloseHandle(hFile);
		hFile = INVALID_HANDLE_VALUE;

closepeer:
		closesocket(peerSk);
		peerSk = INVALID_SOCKET;
	}

	if (hFile != INVALID_HANDLE_VALUE) {
		CloseHandle(hFile);
	}
	if (peerSk != INVALID_SOCKET) {
		closesocket(peerSk);
		peerSk = INVALID_SOCKET;
	}
	if (serverSk != INVALID_SOCKET) {
		closesocket(serverSk);
		serverSk = INVALID_SOCKET;
	}

	return 0;
}
Пример #7
0
int main(int argc, char const *argv[]){
	char port[20];
	char address[50];
	int i, j;

	if (argc<1 || argc>3){
		printf(ILLEGAL_ARGS);
		exit(1);
	}
	if (argc == 1 || argc == 2){
		strcpy(port, DEFAULT_PORT);
		if (argc == 1) strcpy(address, DEFAULT_HOST);
	}
	if (argc == 2 || argc == 3){
		strcpy(address, argv[1]);
		if (argc == 3){
			strcpy(port, argv[2]);
		}
	}
	int sock = socket(AF_INET, SOCK_STREAM, 0); // Get socket
	if (sock == -1){
		printf(SOCKET_ERROR, strerror(errno));
		return errno;
	}
	// Connect to server
	sock = connectToServer(sock, address, port);
	// Get initial data
	char readBuf[BUF_SIZE];
	int bufSize = BUF_SIZE;
	receive_all(sock, readBuf, &bufSize, 1);
	// Get the initial data from the server
	if (game.valid == 0){
		printf(CONNECTION_REJECTION);
		return 0;
	}

	playerId = game.myPlayerId;
	myTurn = game.isMyTurn;
	printf("You are client %d\n", playerId + 1);
	if (playerId == 0){
		printf("Waiting to client 2 to connect.\n");
		receive_all(sock, readBuf, &bufSize, 1); //wait until second player connects
	}

	printGameState(game);
	int addReadyForSend = 0;
	fd_set fdSetRead, fdSetWrite;
	struct clientMsg cm;

	if (myTurn == 1){
		printf(YOUR_TURN);
	}
	while (game.win == -1){
		int maxClientFd = sock;

		FD_ZERO(&fdSetRead);
		FD_ZERO(&fdSetWrite);
		FD_SET(STDIN, &fdSetRead);
		FD_SET(sock, &fdSetRead);

		if (addReadyForSend == 1){
			FD_SET(sock, &fdSetWrite);
		}

		int fdReady = select(maxClientFd + 1, &fdSetRead, &fdSetWrite, NULL, NULL);
		if (fdReady == 0){ //chicken check.
			continue;
		}

		if (FD_ISSET(sock, &fdSetWrite) && addReadyForSend == 1){//packets are ready for send
			int buf = BUF_SIZE;
			char cmBuffer[BUF_SIZE];
			i = 0;
			while (i<cmQueueLength){ //send as fifo
				createClientMsgBuff(cmQueue[i], cmBuffer);
				if (send_all(sock, cmBuffer, &buf) == -1){
					break;
				}
				i++;
			}
			j = -1;
			while (i<cmQueueLength){ //reorganize cmQueue
				j++;
				cmQueue[j] = cmQueue[i];
				i++;
			}
			cmQueueLength = j + 1;
			if (cmQueueLength == 0){ addReadyForSend = 0; };
		}
		if (FD_ISSET(STDIN, &fdSetRead)){// there is input from cmd
			int rSize = BUF_SIZE;
			fgets(readBuf, rSize, stdin);
			cm = getMoveFromInput(sock, readBuf);
			if (cm.msg == 1){ //it's a message! send it right away!
				cmQueue[cmQueueLength] = cm;
				cmQueueLength++;
				addReadyForSend = 1;
			}
			else{//it's a turn.
				if (myTurn != 1){// not my turn!
					printf(MOVE_REJECTED);
				}
				else{
					cmQueue[cmQueueLength] = cm;
					cmQueueLength++;
					addReadyForSend = 1;
				}
			}
		}
		if (FD_ISSET(sock, &fdSetRead)){
			char rBuf[BUF_SIZE];
			int rSize = BUF_SIZE;
			receive_all(sock, rBuf, &rSize, 0);
		}
	}
	printWinner(game);
	return 0;
}
Пример #8
0
/*=============================================================================
Function process_page

Purpose: to search the given page for matches as specified in the command line
         parameters.
          
Parameters:
    *sad (IN) - prepared sockaddr structure
    *host (IN) - the host we are connecting to
    port (IN) - the port we are connecting to
    *fullpath (IN) - the path to the resource we are requesting from host
    *url - URL for page
    *server_context - server part of URL for relative hyperlinks
    *full_context - server and path part of URL for relative hyperlinks
    depth - search depth of page

Returns: nothing, processes the page giving proper reports and adding links
         to the pages to be spidered if under specified depth
=============================================================================*/
void process_page(struct sockaddr *sad, char *host, char *fullpath, char *url,
                  char *server_context, char *full_context, int depth) {
  int sd, done, line, new_bytes, num_bytes, line_match, page_match, start, end;
  char get_request[MAX_URL + strlen("GET  HTTP/1.0\r\n\r\n")];
  char buf[MAX_BUF+1]; /* +1 to let us read MAX_BUF and still null terminate */

  if ((sd=socket(PF_INET, SOCK_STREAM, 0))==-1) {
    printf("unable to create socket\n");
    exit(1);
  }

  if (my_connect(sd,sad,sizeof(*sad),connect_timeout)<0) {
    close(sd);
    if (errno==EINTR)
      printf("connect to %s timed out\n",host);
    else
      printf("unable to connect to %s\n",host);
    return;
  }

  sprintf(get_request,"GET %s HTTP/1.0\r\n\r\n",fullpath);

#ifdef DEBUG
  printf("  sending request: %s",get_request);
#endif

  if (send_all(sd,get_request,strlen(get_request))<strlen(get_request)) {
    printf("problem sending GET request\n");
    close(sd);
    return;
  }

  done = line = num_bytes = page_match = 0;

  while(!done) {

    /* try to get a full buffer of data */
    do {
      new_bytes = recv(sd,buf+num_bytes,MAX_BUF-num_bytes,0);
      if (new_bytes>0)
        num_bytes+=new_bytes;
      else if (new_bytes==0)
        done = 1;
      else if (new_bytes==-1) {
        printf("problem encountered on recv call\n");
        done = 1;
      }
    } while (num_bytes<MAX_BUF && !done);

    buf[num_bytes] = 0; /* terminate for string processing */
    line = start = 0;

    /* process the buffer of data */
    while ((end = strcspn(buf+start,"\n"))+start!=num_bytes) {
      buf[start+end] = 0; /* null terminate */
      if (case_independent)
        line_match = strcasestr(buf+start,pattern) != NULL;
      else
        line_match = strstr(buf+start,pattern) != NULL;
      if (line_match) page_match = 1;
      if (depth < search_depth)
        process_hrefs(buf+start, server_context, full_context, depth);
      line_report(url,line++,buf+start,line_match);
      start+=end+1; /* position for next search */
    }
    /* calculate bytes left over in buf without /n */
    num_bytes -= start;
    if (done) {
      /* process the last line, in MOST cases this is </html> */
      if (case_independent)
        line_match = strcasestr(buf+start,pattern) != NULL;
      else
        line_match = strstr(buf+start,pattern) != NULL;
      if (line_match) page_match = 1;
      if (depth < search_depth)
        process_hrefs(buf+start, server_context, full_context, depth);
      line_report(url,line++,buf+start,line_match);
    } else if (num_bytes==MAX_BUF) {
      /* full buffer with no \n */
      num_bytes = 0; /* allow full buffer read on next pass */
      line--; /* adjust line counter back to proper line */
    } else if (num_bytes) {
      /* bytes left in buffer with no \n, reposition */
      memmove(buf,buf+start,num_bytes);
    } else {
      /* last byte read was \n */
      num_bytes = 0;
    }

  }

  close(sd);
  url_report(url, page_match);
}
Пример #9
0
/*=============================================================================
Function url_content_ok

Purpose: determines if the content at the given URL is ok for processing, that
         is it is text/plain or text/html with no content encoding
          
Parameters:
    *sad (IN) - prepared sockaddr structure
    *url (IN) - the URL we are checking
    *host (IN) - the host we are connecting to
    port (IN) - the port we are connecting to
    *fullpath (IN) - the path to the resource we are requesting from host
        
Returns: 1 if ok to process, 0 otherwise
=============================================================================*/
int url_content_ok(struct sockaddr *sad, char *url, char *host, int port,
                   char *fullpath) {
  int sd, content_ok, done, new_bytes, num_bytes, line, start, end;
  char head_request[MAX_URL + strlen("HEAD  HTTP/1.0\r\n\r\n")];
  char buf[MAX_BUF+1]; /* +1 to let us read MAX_BUF and still null terminate */

  if ((sd=socket(PF_INET, SOCK_STREAM, 0))==-1) {
    printf("unable to create socket\n");
    exit(1);
  }

  if (my_connect(sd,sad,sizeof(*sad),connect_timeout)<0) {
    close(sd);
    if (errno==EINTR)
      printf("connect to %s timed out\n",host);
    else
      printf("unable to connect to %s\n",host);
    return 0;
  }

  sprintf(head_request,"HEAD %s HTTP/1.0\r\n\r\n",fullpath);

#ifdef DEBUG
  printf("  sending request: %s",head_request);
#endif

  if (send_all(sd,head_request,strlen(head_request))<strlen(head_request)) {
    printf("could not send entire HEAD request\n");
    close(sd);
    return 0;
  }

  done = num_bytes = 0;

  /* try to get a buffer of data, we assume HEAD will fit in MAX_BUF bytes */
  do {
    new_bytes = recv(sd,buf+num_bytes,MAX_BUF-num_bytes,0);
    if (new_bytes>0)
      num_bytes+=new_bytes;
    else if (new_bytes==0)
      done = 1;
    else if (new_bytes==-1) {
      printf("problem encountered on recv call\n");
      done = 1;
    }
  } while (num_bytes<MAX_BUF && !done);

  buf[num_bytes] = 0; /* null terminate what was read */
  content_ok = line = start = 0;

  /* process the HEAD buffer */
  while ((end = strcspn(buf+start,"\n"))+start!=num_bytes) {
    buf[start+end] = 0; /* null terminate */
    if (line==0) {
      if (strcasestr(buf+start,"200") == NULL) {
        printf("URL rejected(%s): %s\n",url,buf+start);
        content_ok = 0;
        break;
      }
    } else {
      if (strcasestr(buf+start,"Content-Type:")) {
        if (strcasestr(buf+start,"Content-Type: text/html") ||
            strcasestr(buf+start,"Content-Type: text/plain"))
          content_ok = 1;
        else {
          printf("URL rejected(%s): %s\n",url,buf+start);
          content_ok = 0;
          break;
        }
      }
      if (strcasestr(buf+start,"Content-Encoding:")) {
        printf("URL rejected(%s): %s\n",url,buf+start);
        content_ok = 0;
        break;
      }
    }
    /* some, like www.yahoo.com, send more than HEAD ??? so we break */
    if (strcmp(buf+start,"\r")==0) break;
    start+=end+1; /* position for next search */
    line++;
  }

  close(sd);

  return content_ok;
}
Пример #10
0
	long Socket::send(const std::string &buf) const
	{
		return send_all(this->socket_handle, buf.data(), buf.length() );
	}
Пример #11
0
	long Socket::send(const std::vector<std::string::value_type> &buf, const size_t length) const
	{
		return send_all(this->socket_handle, buf.data(), length);
	}
Пример #12
0
void send_string(int sockfd, char *buf, unsigned int len) {
    send(sockfd, &len, 4, 0);
    send_all(sockfd, buf, len);
}
/****************************************************************
Description : Validate connect 'after' being connected
@arg 		: theList client_list that holds all connections
@arg 		: file_desc socket file descriptor of incoming
@arg 		: port port string of incoming connection
@return 	: bool value indicating (un)successful validation
{9:References}
*****************************************************************/
bool validate_connect(client_list *theList, int file_desc, char *port){

	/******* Validate connect cases *********/

	client_list *loopList = theList;
	bool inSipFlag =false;
	bool alreadyExistFlag =false;
	bool isSelfFlag=false;
	bool isServerFlag=false;
	bool moreThanThree=false;
	char *ipAddr;
	//Get ip address
    while(loopList!=NULL){
        if (loopList->file_desc == file_desc) //Dont consider the last entry
        {
           	ipAddr= loopList->ip_addr;
            break;
        }
        loopList= loopList->cl_next;
    }

    /******* Validate if connecting to server *********/
    loopList=theList;
     while(loopList!=NULL){
        if (loopList->file_desc != file_desc) //Dont consider the last entry
        {
        	if (loopList->connection_id==1)
        	{
        		if (strcmp(loopList->ip_addr,ipAddr)==0)
        		{
        			if (strcmp(loopList->port,port)==0)
        			{
        				isServerFlag = true;
        				break;
        			}
        		}
        	}
        }
     	loopList= loopList->cl_next;    	
    }

    if (isServerFlag)
    {
    	send_all(file_desc,"41 error-c Connect to server not allowed ",41);
    	client_list *current;
    	get_list_entry(theList,&current,file_desc);
    	fprintf(stderr, "%s (%s) tried connect. Connection declined.\n",
    		current->host_name,current->ip_addr);
    	return false;
    }

    /******* Validate if in sip *********/
    loopList = sip_list;
    
    while(loopList!=NULL){
    	if (strcmp(loopList->ip_addr,ipAddr)==0)
    	{
    		if (strcmp(loopList->port,port)==0)
    		{
    			inSipFlag = true;
    			break;
    		}
    	}
        loopList= loopList->cl_next;
    }

    if (!inSipFlag) //checks if self registered too
    {
    	if (sip_list==NULL)
    	{
    		send_all(file_desc,"50 error-c Destination not registered with server ",50);
    		fprintf(stderr, "Self not registered. Connection declined.\n");
    	}else{
    		send_all(file_desc,"38 error-c Not registered with server ",38);
    		client_list *current;
    		get_list_entry(theList,&current,file_desc);
    		fprintf(stderr, "%s (%s) not registered. Connection declined.\n",
    			current->host_name,current->ip_addr);
    	}
    	return false;
    }


    /******* Validate if connection is duplicate *********/
    loopList=theList;
    while(loopList!=NULL){
        if (loopList->file_desc != file_desc) //Dont consider the last entry
        {
        	if (strcmp(loopList->ip_addr,ipAddr)==0)
        	{
        		if (strcmp(loopList->port,port)==0)
        		{
        			alreadyExistFlag = true;
        			break;
        		}
        	}
        }
        loopList = loopList->cl_next;
    }
    if (alreadyExistFlag)
    {
    	send_all(file_desc,"29 error-c Already connected ",29);
    	client_list *current;
    	get_list_entry(theList,&current,file_desc);
    	fprintf(stderr, "%s (%s) already connected. Duplicate connection declined.\n",
    		current->host_name,current->ip_addr);
    	return false;
    }

    /******* Validate if connection is to self *********/
    commandMyip(); //make sure my_ip_addr is valid
    if (strcmp(ipAddr,my_ip_addr)==0||
    	strcmp(ipAddr,"127.0.0.1")==0)
    {
    	if (strcmp(listening_port,port)==0)
    	{
    		isSelfFlag=1;
    	}
    }
    if (isSelfFlag)
    {
    	client_list *current;
    	get_list_entry(theList,&current,file_desc);
    	send_all(file_desc,"11 error-c ",11);
    	fprintf(stderr, "%s %s is self. Self connection declined.\n",
    		current->host_name,current->ip_addr);
    	return false;
    }

    loopList=theList;
    int connectionCount =0;
    while(loopList!=NULL){
        if (loopList->file_desc != file_desc) //Dont consider the last entry
        {
        	connectionCount++;
        	if (connectionCount>3)
        	{
        		moreThanThree=true;
        	}
        }
        loopList = loopList->cl_next;
    }
    if (moreThanThree)
    {
    	send_all(file_desc,"52 error-c Destination already connected to 3 peers ",52);
    	client_list *current;
    	get_list_entry(theList,&current,file_desc);
    	fprintf(stderr, "%s (%s) Maximum connections reached. New connection declined.\n",
    		current->host_name,current->ip_addr);
    	return false;
    }

    return true;

}
Пример #14
0
int main(int argc,char** argv)
{
	int i,j,fd;
	int n=0;
  char buffer[100];
	int closed=0;
	int numsplitters=atoi(argv[2]);
   int id=atoi(argv[1]);
builder_List lista=builder_create_list();
	char*pipe_name;

double t1, t2, cpu_time;
struct tms tb1, tb2;
double ticspersec;
int  sum = 0;
ticspersec = (double) sysconf(_SC_CLK_TCK);
t1 = (double) times(&tb1);






struct pollfd pfds[numsplitters];


for (i=0;i<numsplitters;i++){
  	pipe_name=name_of_pipe(i,id);
	
	pfds[i].fd =open(pipe_name, O_RDONLY);
	pfds[i].events = POLLIN;
}

printf("perasa tin loopa twn splitter\n");

int k=0;

while(closed<numsplitters){

int num = poll(pfds, numsplitters, -1);
int ar=0;
if(num != 0)
        {
             if (num == -1)
             {
                 perror("poll");
                 exit(1);
             }

             for(j = 0; j < numsplitters; j++)
             {
                 if(pfds[j].revents & POLLIN)
                 {
					if(read_data (pfds[j].fd ,buffer)>0){
                    
					ar++;
								
					if (strcmp(buffer,"oulala")==0){
						closed++;	

						}
					else{
  	      			if(builder_search_list(lista,buffer)!=1)	
						builder_insert_to_end(lista,builder_create_node(buffer)); 


} }
					        
                 }
             }
         }
}


// teleiwse to diavasma apo tous splitters twra stelnw sto root

pipe_name=name_of_pipe(-1,id);


send_all(lista,pipe_name);



printf("builder %d closed \n",id);


t2 = (double) times(&tb2);
cpu_time = (double) ((tb2.tms_utime + tb2.tms_stime) -
(tb1.tms_utime + tb1.tms_stime));
//printf("Run time was %lf sec (REAL time) although we used the CPU for %lf sec (CPU time).\n",(t2 - t1)/ticspersec,cpu_time/ticspersec);
free(pipe_name);
FILE * fpa;
fpa = fopen (argv[3], "a");
fprintf(fpa,"BUILDER %d : (REAL time) %lf sec    (CPU time) %lf sec \n",id,(t2 - t1)/ticspersec,cpu_time/ticspersec);
//sleep(3);
fclose(fpa);
kill(getppid(),SIGRTMIN+2);
kill(getppid(),SIGUSR2);



}
Пример #15
0
	void net_process() {
		while (true) {
			struct bitcoin_msg_header header;
			if (read_all(sock, (char*)&header, sizeof(header)) != sizeof(header))
				return disconnect("failed to read message header");

			if (header.magic != BITCOIN_MAGIC)
				return disconnect("invalid magic bytes");

			struct timeval start_read;
			gettimeofday(&start_read, NULL);

			header.length = le32toh(header.length);
			if (header.length > 5000000)
				return disconnect("got message too large");

			auto msg = std::make_shared<std::vector<unsigned char> > (sizeof(struct bitcoin_msg_header) + uint32_t(header.length));
			if (read_all(sock, (char*)&(*msg)[sizeof(struct bitcoin_msg_header)], header.length) != int(header.length))
				return disconnect("failed to read message");

			unsigned char fullhash[32];
			CSHA256 hash;
			hash.Write(&(*msg)[sizeof(struct bitcoin_msg_header)], header.length).Finalize(fullhash);
			hash.Reset().Write(fullhash, sizeof(fullhash)).Finalize(fullhash);
			if (memcmp((char*)fullhash, header.checksum, sizeof(header.checksum)))
				return disconnect("got invalid message checksum");

			if (!strncmp(header.command, "version", strlen("version"))) {
				if (connected != 0)
					return disconnect("got invalid version");
				connected = 1;

				if (header.length < sizeof(struct bitcoin_version_start))
					return disconnect("got short version");
				struct bitcoin_version_start *their_version = (struct bitcoin_version_start*) &(*msg)[sizeof(struct bitcoin_msg_header)];

				printf("%s Protocol version %u\n", host.c_str(), le32toh(their_version->protocol_version));

				struct bitcoin_version_with_header version_msg;
				version_msg.version.start.timestamp = htole64(time(0));
				memcpy(((char*)&version_msg.version.end.user_agent) + 27, location, 7);
				static_assert(BITCOIN_UA_LENGTH == 27 + 7 + 2 /* 27 + 7 + '/' + '\0' */, "BITCOIN_UA changed in header but file not updated");

				prepare_message("version", (unsigned char*)&version_msg, sizeof(struct bitcoin_version));
				if (send_all(sock, (char*)&version_msg, sizeof(struct bitcoin_version_with_header)) != sizeof(struct bitcoin_version_with_header))
					return disconnect("failed to send version message");

				struct bitcoin_msg_header verack_header;
				prepare_message("verack", (unsigned char*)&verack_header, 0);
				if (send_all(sock, (char*)&verack_header, sizeof(struct bitcoin_msg_header)) != sizeof(struct bitcoin_msg_header))
					return disconnect("failed to send verack");

				continue;
			} else if (!strncmp(header.command, "verack", strlen("verack"))) {
				if (connected != 1)
					return disconnect("got invalid verack");
				connected = 2;
				send_mutex.unlock();

				continue;
			}

			if (connected != 2)
				return disconnect("got non-version, non-verack before version+verack");

			if (!strncmp(header.command, "ping", strlen("ping"))) {
				memcpy(&header.command, "pong", sizeof("pong"));
				memcpy(&(*msg)[0], &header, sizeof(struct bitcoin_msg_header));
				std::lock_guard<std::mutex> lock(send_mutex);
				if (send_all(sock, (char*)&(*msg)[0], sizeof(struct bitcoin_msg_header) + header.length) != int64_t(sizeof(struct bitcoin_msg_header) + header.length))
					return disconnect("failed to send pong");
				continue;
			} else if (!strncmp(header.command, "inv", strlen("inv"))) {
				std::lock_guard<std::mutex> lock(send_mutex);

				try {
					std::set<std::vector<unsigned char> > setRequestBlocks;
					std::set<std::vector<unsigned char> > setRequestTxn;

					std::vector<unsigned char>::const_iterator it = msg->begin();
					it += sizeof(struct bitcoin_msg_header);
					uint64_t count = read_varint(it, msg->end());
					if (count > 50000)
						return disconnect("inv count > MAX_INV_SZ");

					uint32_t MSG_TX = htole32(1);
					uint32_t MSG_BLOCK = htole32(2);

					for (uint64_t i = 0; i < count; i++) {
						move_forward(it, 4 + 32, msg->end());
						std::vector<unsigned char> hash(it-32, it);

						const uint32_t type = (*(it-(1+32)) << 24) | (*(it-(2+32)) << 16) | (*(it-(3+32)) << 8) | *(it-(4+32));
						if (type == MSG_TX) {
							if (!txnAlreadySeen.insert(hash).second)
								continue;
							setRequestTxn.insert(hash);
						} else if (type == MSG_BLOCK) {
							if (!blocksAlreadySeen.insert(hash).second)
								continue;
							setRequestBlocks.insert(hash);
						} else
							return disconnect("unknown inv type");
					}

					if (setRequestBlocks.size()) {
						std::vector<unsigned char> getdataMsg;
						std::vector<unsigned char> invCount = varint(setRequestBlocks.size());
						getdataMsg.reserve(sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestBlocks.size()*36);

						getdataMsg.insert(getdataMsg.end(), sizeof(struct bitcoin_msg_header), 0);
						getdataMsg.insert(getdataMsg.end(), invCount.begin(), invCount.end());

						for (auto& hash : setRequestBlocks) {
							getdataMsg.insert(getdataMsg.end(), (unsigned char*)&MSG_BLOCK, ((unsigned char*)&MSG_BLOCK) + 4);
							getdataMsg.insert(getdataMsg.end(), hash.begin(), hash.end());
						}

						prepare_message("getdata", (unsigned char*)&getdataMsg[0], invCount.size() + setRequestBlocks.size()*36);
						if (send_all(sock, (char*)&getdataMsg[0], sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestBlocks.size()*36) !=
								int(sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestBlocks.size()*36))
							return disconnect("error sending getdata");

						for (auto& hash : setRequestBlocks) {
							struct timeval tv;
							gettimeofday(&tv, NULL);
							for (unsigned int i = 0; i < hash.size(); i++)
								printf("%02x", hash[hash.size() - i - 1]);
							printf(" requested from %s at %lu\n", host.c_str(), uint64_t(tv.tv_sec) * 1000 + uint64_t(tv.tv_usec) / 1000);
						}
					}

					if (setRequestTxn.size()) {
						std::vector<unsigned char> getdataMsg;
						std::vector<unsigned char> invCount = varint(setRequestTxn.size());
						getdataMsg.reserve(sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestTxn.size()*36);

						getdataMsg.insert(getdataMsg.end(), sizeof(struct bitcoin_msg_header), 0);
						getdataMsg.insert(getdataMsg.end(), invCount.begin(), invCount.end());

						for (const std::vector<unsigned char>& hash : setRequestTxn) {
							getdataMsg.insert(getdataMsg.end(), (unsigned char*)&MSG_TX, ((unsigned char*)&MSG_TX) + 4);
							getdataMsg.insert(getdataMsg.end(), hash.begin(), hash.end());
						}

						prepare_message("getdata", (unsigned char*)&getdataMsg[0], invCount.size() + setRequestTxn.size()*36);
						if (send_all(sock, (char*)&getdataMsg[0], sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestTxn.size()*36) !=
								int(sizeof(struct bitcoin_msg_header) + invCount.size() + setRequestTxn.size()*36))
							return disconnect("error sending getdata");
					}
				} catch (read_exception) {
					return disconnect("failed to process inv");
				}
				continue;
			}

			memcpy(&(*msg)[0], &header, sizeof(struct bitcoin_msg_header));
			if (!strncmp(header.command, "block", strlen("block"))) {
				provide_block(this, msg, start_read);
			} else if (!strncmp(header.command, "tx", strlen("tx"))) {
				provide_transaction(this, msg);
			}
		}
	}
Пример #16
0
int chitcpd_tcp_state_handle_ESTABLISHED(serverinfo_t *si, chisocketentry_t *entry, tcp_event_type_t event){
  tcp_data_t *data = &entry->socket_state.active.tcp_data;
  if (event == APPLICATION_SEND) {      
    send_all(si,entry,data);
  } else if (event == PACKET_ARRIVAL) {
    while (!list_empty(&data->pending_packets) && circular_buffer_available(&data->recv)){
      pthread_mutex_lock(&data->lock_pending_packets);
      tcp_packet_t *pack = list_fetch(&(data->pending_packets));
      pthread_mutex_unlock(&data->lock_pending_packets);
      tcphdr_t * head = TCP_PACKET_HEADER(pack);
    
      if (!acceptability_test(data, pack)) {
	send_ACK(si, entry, data);
	chitcp_tcp_packet_free(pack);
	return CHITCP_OK; 
      }
     
      if (!head->syn && head->ack) {
	if (inside_window(data, pack))
	  update_WND_and_UNA(data, pack);

	if (TCP_PAYLOAD_LEN(pack))
	  use_data(si, entry, data, pack);

	if (head->fin){
	  always_on_fb(si, entry, data, pack);  
	  chitcpd_update_tcp_state(si, entry, CLOSE_WAIT);
	}	
      }
      chitcp_tcp_packet_free(pack);
    }
  } else if (event == APPLICATION_RECEIVE){

    data->RCV_WND = circular_buffer_available(&data->recv); 
  

  } else if (event == APPLICATION_CLOSE){
    
    send_all(si,entry,data);
    
    tcp_packet_t *new_pack = (tcp_packet_t*)malloc(sizeof(tcp_packet_t));
    chitcpd_tcp_packet_create(entry,new_pack,NULL,0);
    tcphdr_t *FIN = TCP_PACKET_HEADER(new_pack);
	
    FIN->seq = chitcp_htonl(data->SND_NXT);
    FIN->ack_seq = chitcp_htonl(data->RCV_NXT);
    FIN->fin = 1;
    FIN->win = chitcp_htons(data->RCV_WND);

    chilog_tcp(CRITICAL,new_pack,LOG_OUTBOUND);
    chitcpd_send_tcp_packet(si,entry,new_pack);
    
    circular_buffer_close(&data->recv);
    circular_buffer_close(&data->send);
    
    chitcpd_update_tcp_state(si,entry,FIN_WAIT_1);

    chitcp_tcp_packet_free(new_pack);
  }
  else
    chilog(WARNING, "In ESTABLISHED state, received unexpected event (%i).", event);

  return CHITCP_OK;
}
Пример #17
0
int main(int argc, char *argv[])
{
    if (argc < 1) {
        dprintf(STDERR_FILENO, "wrun called without argument\n");
        terminate_nocore();
    }
    shift(&argc, &argv);
    if (argc > 1 && !strcmp(argv[0], "--tool_name")) {
        shift(&argc, &argv);
        tool_name = shift(&argc, &argv);
    }

    fill_std_fd_info_identity(STDIN_FILENO);
    fill_std_fd_info_identity(STDOUT_FILENO);
    fill_std_fd_info_identity(STDERR_FILENO);

    bool force_redirects = false;
    bool silent_breakaway = false;

    int port;
    bool terminate = !get_outbash_infos(&port, &force_redirects);

    struct string outbash_command = string_create("");

    if (argc && !strcmp(argv[0], ":")) {
        shift(&argc, &argv);
        string_append(&outbash_command, "cd:~\n");
    } else {
        char* cwd = agetcwd();
        if (is_absolute_drive_fs_path(cwd)) {
            char* cwd_win32 = convert_drive_fs_path_to_win32(cwd);
            string_append(&outbash_command, "cd:");
            string_append(&outbash_command, cwd_win32);
            string_append(&outbash_command, "\n");
            free(cwd_win32);
        }
        free(cwd);
    }

    while (argc && !strncmp(argv[0], "--", 2)) {

        if (!strcmp(argv[0], "--")) {
            shift(&argc, &argv);
            break;
        }

        if (!strcmp(argv[0], "--env")) {
            shift(&argc, &argv);
            while (argc && strncmp(argv[0], "--", 2) != 0
                        && *argv[0] != '\0' && strchr(argv[0] + 1, '=')) {
                string_append(&outbash_command, "env:");
                string_append(&outbash_command, argv[0]);
                string_append(&outbash_command, "\n");
                shift(&argc, &argv);
            }
        } else if (!strcmp(argv[0], "--force-redirects")) {
            force_redirects = true;
            shift(&argc, &argv);
        } else if (!strcmp(argv[0], "--silent-breakaway")) {
            silent_breakaway = true;
            shift(&argc, &argv);
        } else if (!strcmp(argv[0], "--help")) {
            print_help();
            exit(1);
        } else {
            dprintf(STDERR_FILENO, "%s: unknown command line option: %s\n", tool_name, argv[0]);
            dprintf(STDERR_FILENO, "type %s --help for more information.\n", tool_name);
            terminate_nocore();
        }
    }
    if (terminate)
        terminate_nocore();
    check_argc(argc);

    decide_will_redirect(STDIN_FILENO,  force_redirects);
    decide_will_redirect(STDOUT_FILENO, force_redirects);
    decide_will_redirect(STDERR_FILENO, force_redirects);

    int sock_ctrl = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sock_ctrl < 0) {
        dprintf(STDERR_FILENO, "%s: socket() failed: %s\n", tool_name, my_strerror(errno));
        terminate_nocore();
    }

#define STDIN_NEEDS_SOCKET_REDIRECT     1
#define STDOUT_NEEDS_SOCKET_REDIRECT    2
#define STDERR_NEEDS_SOCKET_REDIRECT    4
#define STDERR_SOCKREDIR_TO_STDOUT      8
    int redirects =   (needs_socket_redirect(STDIN_FILENO)  ? STDIN_NEEDS_SOCKET_REDIRECT  : 0)
                    | (needs_socket_redirect(STDOUT_FILENO) ? STDOUT_NEEDS_SOCKET_REDIRECT : 0);
    if (needs_socket_redirect(STDERR_FILENO)) {
        if ((redirects & STDOUT_NEEDS_SOCKET_REDIRECT) && are_stdfd_to_same_thing(STDOUT_FILENO, STDERR_FILENO))
            redirects |= STDERR_SOCKREDIR_TO_STDOUT;
        else
            redirects |= STDERR_NEEDS_SOCKET_REDIRECT;
    }

    struct listening_socket lsock_in = NO_LISTENING_SOCKET;
    struct listening_socket lsock_out = NO_LISTENING_SOCKET;
    struct listening_socket lsock_err = NO_LISTENING_SOCKET;
    if (redirects & STDIN_NEEDS_SOCKET_REDIRECT) lsock_in = socket_listen_one_loopback();
    if (redirects & STDOUT_NEEDS_SOCKET_REDIRECT) lsock_out = socket_listen_one_loopback();
    if (redirects & STDERR_NEEDS_SOCKET_REDIRECT) lsock_err = socket_listen_one_loopback();
    ask_redirect(&outbash_command, "stdin:", STDIN_FILENO, lsock_in.port);
    ask_redirect(&outbash_command, "stdout:", STDOUT_FILENO, lsock_out.port);
    ask_redirect(&outbash_command, "stderr:", STDERR_FILENO,
                 (redirects & STDERR_NEEDS_SOCKET_REDIRECT) ? lsock_err.port : lsock_out.port);

    if (silent_breakaway)
        string_append(&outbash_command, "silent_breakaway:1\n");

    char* win32_module;
    if (is_absolute_drive_fs_path(argv[0])) {
        win32_module = convert_drive_fs_path_to_win32(argv[0]);
        string_append(&outbash_command, "module:");
        string_append(&outbash_command, win32_module);
        string_append(&outbash_command, "\n");
    } else {
        win32_module = convert_slash_to_backslash(argv[0]);
    }

    const bool module_need_quotes = (NULL != strpbrk(win32_module, " \t"));
    string_append(&outbash_command, "run:");
    if (module_need_quotes)
        string_append(&outbash_command, "\"");
    string_append(&outbash_command, win32_module);
    if (module_need_quotes)
        string_append(&outbash_command, "\"");

    free(win32_module);

    for (int i = 1; i < argc; i++) {
        string_append(&outbash_command, " ");
        string_append(&outbash_command, argv[i]);
    }
    string_append(&outbash_command, "\n\n");
    //dprintf(STDOUT_FILENO, "%s", outbash_command.str);
    //return EXIT_FAILURE;

    signal(SIGPIPE, SIG_IGN);

    sigset_t signal_set, orig_mask;

    //////////////////////////// unblock SIGUSR1
    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGUSR1);
    pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL);

    //////////////////////////// block SIGTSTP
    sigemptyset(&signal_set);
    sigaddset(&signal_set, SIGTSTP);
    pthread_sigmask(SIG_BLOCK, &signal_set, &orig_mask);

    //////////////////////////// install custom SIGTSTP handler if signal was not ignored
    struct sigaction sa;
    sigaction(SIGTSTP, NULL, &sa);
    const bool ignore_sigtstp = (sa.sa_handler == SIG_IGN);
    if (!ignore_sigtstp) {
        sa.sa_handler = tstop_handler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        sigaction(SIGTSTP, &sa, NULL);
    }

    //////////////////////////// install custom SIGUSR1 handler to wake-up blocked IO forwarding threads
    // NOTE: the handler itself do nothing, but any blocked syscall will return with EINTR error
    sa.sa_handler = noop_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGUSR1, &sa, NULL);

    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    serv_addr.sin_port = htons(port);
    if (connect(sock_ctrl, (const struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        // NOTE: I'm not sure that WSL does what Linux does concerning
        // http://www.madore.org/~david/computers/connect-intr.html
        // for now we do not expect to recover after an interruption here.
        dprintf(STDERR_FILENO, "%s: connect() failed: %s\n", tool_name, my_strerror(errno));
        terminate_nocore();
    }

    if (send_all(sock_ctrl, outbash_command.str, outbash_command.length, 0) < 0) {
        dprintf(STDERR_FILENO, "%s: send_all() failed: %s\n", tool_name, my_strerror(errno));
        terminate_nocore();
    }
    string_destroy(&outbash_command);

    static struct forward_state fs[3];
    fs_init_accept_as_needed(&fs[STDIN_FILENO],  &lsock_in,  redirects & STDIN_NEEDS_SOCKET_REDIRECT,  STDIN_FILENO,  "stdin");
    fs_init_accept_as_needed(&fs[STDOUT_FILENO], &lsock_out, redirects & STDOUT_NEEDS_SOCKET_REDIRECT, STDOUT_FILENO, "stdout");
    fs_init_accept_as_needed(&fs[STDERR_FILENO], &lsock_err, redirects & STDERR_NEEDS_SOCKET_REDIRECT, STDERR_FILENO, "stderr");

    char *line = ctrl_readln(sock_ctrl, NULL);
    if (!line || strcmp(line, "connected")) {
        dprintf(STDERR_FILENO, "%s: did not receive connection validation from outbash.exe\n", tool_name);
        terminate_nocore();
    }

    close_listener(&lsock_in);
    close_listener(&lsock_out);
    close_listener(&lsock_err);

    enum state_e state = RUNNING;
    int program_return_code = 255;

    pthread_t   forward_threads[3];
    bool        active_threads[3] = {0};

    for (int i = 0; i < 3; i++) {
        if ((!fs[i].dead_in) || (!fs[i].dead_out)) {
            int err = pthread_create(&forward_threads[i], NULL, forward_one_stream, &fs[i]);
            if (err != 0) {
                dprintf(STDERR_FILENO, "%s: pthread_create() failed: %s\n", tool_name, my_strerror(err));
                terminate_nocore();
            }
            active_threads[i] = true;
        }
    }

    int nfds = sock_ctrl + 1;

    while (state != TERMINATED) {
        fd_set rfds;
        FD_ZERO(&rfds);
        if (sock_ctrl < 0 || sock_ctrl >= FD_SETSIZE) {
            dprintf(STDERR_FILENO, "%s: sock_ctrl=%d out of range\n", tool_name, sock_ctrl);
            abort();
        }
        FD_SET(sock_ctrl, &rfds);

        int pselect_res = pselect(nfds, &rfds, NULL, NULL, NULL, &orig_mask); // tstop_handler can run here
        int pselect_errno = errno;

        if (tstop_req && state == RUNNING) {
            int r = send_all(sock_ctrl, "suspend\n", strlen("suspend\n"), 0);
            if (r < 0 && err_is_connection_broken(errno)) {
                // We will never be able to ask outbash to suspend the
                // Windows process, the expected reason is that it actually
                // has already terminated and we don't know yet about that,
                // so stop the suspend forwarding mechanism and suspend
                // ourselves immediately.
                shutdown(sock_ctrl, SHUT_WR); // also we can't send anything anymore // XXX to comment for WSL bug workaround? proba low here...
                signal(SIGTSTP, SIG_DFL);
                state = DYING;
                raise(SIGTSTP);
                pthread_sigmask(SIG_SETMASK, &orig_mask, NULL);
            } else if (r < 0) { // other errors
                dprintf(STDERR_FILENO, "%s: send_all(\"suspend\\n\") failed: %s\n", tool_name, my_strerror(errno));
                abort();
            } else { // OK
                // It's up to outbash now, just wait for its "suspend_ok"
                // answer after it has suspended the Windows process.
                state = SUSPEND_PENDING;
            }
        }

        if (pselect_res < 0 && pselect_errno == EINTR) {
            // "On error, -1 is returned, and errno is set appropriately;
            //  the sets and timeout become undefined, so do not rely on
            //  their contents after an error."
            continue;
        }

        if (pselect_res < 0) {
            dprintf(STDERR_FILENO, "%s: pselect() failed: %s\n", tool_name, my_strerror(pselect_errno));
            abort();
        }

        if (FD_ISSET(sock_ctrl, &rfds)) {
            while (1) {
                int nonblock_marker;
                line = ctrl_readln(sock_ctrl, &nonblock_marker);
                if (!line && nonblock_marker) break;
                if (line && !strcmp(line, "suspend_ok")) {
                    if (state == SUSPEND_PENDING) {
                        signal(SIGTSTP, SIG_DFL);
                        raise(SIGTSTP);
                        sigset_t previous_mask;
                        pthread_sigmask(SIG_SETMASK, &orig_mask, &previous_mask);
                            // >>> Process will Stop here, until SIGCONT <<<
                        pthread_sigmask(SIG_SETMASK, &previous_mask, NULL);
                        tstop_req = 0;
                        int r = send_all(sock_ctrl, "resume\n", strlen("resume\n"), 0);
                        if (r < 0 && err_is_connection_broken(errno)) {
                            // killed when suspended (if this is possible?)
                            // or maybe just before an attempt?
                            shutdown(sock_ctrl, SHUT_WR); // XXX to comment for WSL bug workaround? proba low here...
                            state = DYING;
                            pthread_sigmask(SIG_SETMASK, &orig_mask, NULL);
                        } else if (r < 0) {
                            dprintf(STDERR_FILENO, "%s: send_all(\"resume\\n\") failed: %s\n", tool_name, my_strerror(errno));
                            abort();
                        } else {
                            state = RUNNING;
                            sa.sa_handler = tstop_handler;
                            sigemptyset(&sa.sa_mask);
                            sa.sa_flags = 0;
                            sigaction(SIGTSTP, &sa, NULL);
                        }
                    } else {
                        dprintf(STDERR_FILENO, "%s: spurious \"suspend_ok\" received\n", tool_name);
                    }
                } else { // not "suspend_ok" => for now only other cases are exit conditions
                    program_return_code = get_return_code(line);
                    shutdown(sock_ctrl, SHUT_RDWR);
                    signal(SIGTSTP, ignore_sigtstp ? SIG_IGN : SIG_DFL);
                    if ((tstop_req && state == RUNNING) || state == SUSPEND_PENDING) {
                        // We expect to stop soon, but not without flushing the OS TCP
                        // buffers and our owns, and other WSL processes in a pipe might
                        // already be suspended, so we better honor suspend requests ASAP.
                        raise(SIGTSTP);
                    }
                    pthread_sigmask(SIG_SETMASK, &orig_mask, NULL);
                    tstop_req = 0;
                    state = TERMINATED;
                    break;
                }
            }
        }
    }

    // XXX: this is not ideal if the Win32 side managed to maintain the
    // redirection socket beyond the lifetime of the launched process,
    // however things seem to already be not reliable for Windows reasons
    // in this case
    if (active_threads[0]) {
        __sync_fetch_and_add(&fs[0].ask_terminate, 1);
        useconds_t usec_sleep = 1000;
        while (!__sync_fetch_and_add(&fs[0].finished, 0)) {
            pthread_kill(forward_threads[0], SIGUSR1);
            usleep(usec_sleep);
            usec_sleep *= 2;
            if (usec_sleep > 60000000)
                usec_sleep = 60000000;
        }
    }

    for (int i = 0; i < 3; i++)
        if (active_threads[i])
            pthread_join(forward_threads[i], NULL);

    return program_return_code;
}
Пример #18
0
int main (int argc, char *argv[])
{
    int sockfd, numbytes, msglen, ret;
    char buf[MAXDATASIZE], msg[MAXDATASIZE], *newline;
    char res[MAXDATASIZE];
    char *irc_host, *irc_port, *irc_chan, *irc_nick, *irc_pass, *irc_name;
    char *irc_nick_ping;

    MYSQL *db;

    sockfd = open_irc_socket (&irc_host, &irc_port, &irc_chan, &irc_nick, &irc_pass, &irc_name);
    if (sockfd < 0)
    {
        return 1;
    }

    db = open_database ();
    if (db == NULL)
    {
        close (sockfd);
        return 1;
    }

    snprintf (res, MAXDATASIZE, "%s:", irc_nick);
    irc_nick_ping = strdup (res);

    numbytes = 0;
    buf[0] = '\0';
    while (1)
    {
        char *msgtype, *recipient, *sender, *contents;

        while (!(newline = strstr (buf, "\r\n")))
        {
            ret = recv (sockfd, buf + numbytes, MAXDATASIZE - numbytes - 1, 0);
            if (ret == -1)
            {
                perror ("recv");
                break;
            }
            else if (ret == 0)
                break;

            numbytes += ret;
        }

        msglen = newline + 2 - buf;
        strncpy (msg, buf, numbytes);
        numbytes -= msglen;
        strncpy (buf, msg + msglen, numbytes);
        msg[msglen - 2] = '\0';
        buf[numbytes] = '\0';

        printf ("%s\n", msg);

        sender = msg + 1;

        msgtype = strchr (msg, ' ');
        if (!msgtype)
            continue;
        msgtype[0] = '\0';
        msgtype++;

        if (strcmp (msg, "PING") == 0)
        {
            /* PING has msgtype as the sender */
            snprintf (res, MAXDATASIZE, "PONG :%s\r\n", msgtype);
            send_all (sockfd, res);
        }

        recipient = strchr (msgtype, ' ');
        if (!recipient)
            continue;
        recipient[0] = '\0';
        recipient++;

        contents = strchr (recipient, ' ');
        if (!contents)
            continue;
        contents[0] = '\0';
        contents += 2;

        if (strcmp (msgtype, "PRIVMSG") == 0)
        {
            char *send_to, *temp1;
            char **args;
            int arg_len;

            args = NULL;
            arg_len = 0;
            send_to = NULL;

            if (strcmp (recipient, irc_nick) == 0)
            {
                char *sep;

                send_to = strdup (sender);
                arg_len = parse_command (contents, &args);

                sep = strchr (send_to, '!');
                if (sep)
                    *sep = '\0';
            }
            else if (strncmp (contents, irc_nick_ping, strlen (irc_nick_ping)) == 0)
            {
                send_to = strdup (recipient);
                arg_len = parse_command (contents + strlen (irc_nick_ping), &args);
            }

            if (arg_len > 0)
            {
                if (strcmp (args[0], "add") == 0)
                {
                    if (strcmp (args[1], "genre") == 0)
                    {
                        char *title, *name;

                        title = arg_len > 2? args[2] : NULL;
                        name = arg_len > 3? args[3] : NULL;

                        switch (genre_add (db, title, name))
                        {
                            case ERR_GENRE_TITLE_EMPTY:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Please specify a title for the genre.\r\n",
                                          send_to);
                                send_all (sockfd, res);

                                break;

                            case ERR_GENRE_TITLE_EXIST:
                                temp1 = malloc (strlen (title) * 2 + 1);
                                mysql_real_escape_string (db, temp1, title, strlen (title));

                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :The genre \"%s\" already exists.\r\n",
                                          send_to, temp1);
                                send_all (sockfd, res);

                                free (temp1);

                                break;

                            case ERR_GENRE_NAME_EXIST:
                                temp1 = malloc (strlen (name) * 2 + 1);
                                mysql_real_escape_string (db, temp1, name, strlen (name));

                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :The genre with name \"%s\" already exists.\r\n",
                                          send_to, temp1);
                                send_all (sockfd, res);

                                free (temp1);

                                break;

                            case ERR_QUERY_FAILED:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Sorry, an internal error occured. Please contact the administrators.\r\n",
                                          send_to);
                                send_all (sockfd, res);

                                break;

                            default:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Successfully added genre \"%s\"!\r\n",
                                          send_to, title);
                                send_all (sockfd, res);

                                break;
                        }
                    }
                }
                else if (strcmp (args[0], "remove") == 0)
                {
                    if (strcmp (args[1], "genre") == 0)
                    {
                        char *genre;
                        int ret;

                        genre = arg_len > 2? args[2] : NULL;
                        ret = genre_remove_with_title (db, genre);

                        if (ret == ERR_GENRE_TITLE_DONT_EXIST)
                            ret = genre_remove_with_name (db, genre);

                        switch (ret)
                        {
                            case ERR_GENRE_TITLE_EMPTY:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Please specify the title of the genre.\r\n",
                                          send_to);
                                send_all (sockfd, res);

                                break;

                            case ERR_GENRE_TITLE_DONT_EXIST:
                            case ERR_GENRE_NAME_DONT_EXIST:
                                temp1 = malloc (strlen (genre) * 2 + 1);
                                mysql_real_escape_string (db, temp1, genre, strlen (genre));

                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :The genre with title nor name \"%s\" doesn't exists.\r\n",
                                          send_to, temp1);
                                send_all (sockfd, res);

                                free (temp1);

                                break;

                            case ERR_QUERY_FAILED:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Sorry, an internal error occured. Please contact the administrators.\r\n",
                                          send_to);
                                send_all (sockfd, res);

                                break;

                            default:
                                snprintf (res, MAXDATASIZE,
                                          "PRIVMSG %s :Successfully removed genre \"%s\"!\r\n",
                                          send_to, genre);
                                send_all (sockfd, res);

                                break;
                        }
                    }
                }
            }

            if (args)
            {
                int i;

                for (i = 0; i < arg_len; i++)
                    free (args[i]);

                free (args);
            }

            if (send_to)
                free (send_to);
        }
    }

    free (irc_nick_ping);

    mysql_close (db);
    close (sockfd);

    free (irc_host);
    free (irc_port);
    free (irc_chan);
    free (irc_nick);
    free (irc_pass);
    free (irc_name);

    return 0;
}
Пример #19
0
int
main(int argc, char **argv)
{
	
	int n, i, size, prflag;
	int pos = 3;
	int maxfd;
	int rt_sockfd,recv_ping_sockfd;
	int send_mulcst_fd, recv_mulcst_fd;
	const int on = 1;
	
	char buff_recv[BUFFSIZE];
	char tour_array[TOURNUM][IPLEN];
	char *ptr;

	fd_set  rset;
	struct timeval tval, tval1, tval2, tval3, tval4;
	struct sockaddr_ll saddrll;

	Signal(SIGALRM, sig_alrm);
	//Signal(SIGCHLD, sig_chld);
	uname(&myname);
	
	if (argc == 1){
		fputs("This is NOT source node\n", stdout);
		//_is_src_node = 0;
		source_flag = 0;
	}else{
		fputs("I'm source node, start to send tour infomation \n", stdout);
		//_is_src_node = 1;
		source_flag = 1;
	}

	
	//if (uname(&myname) < 0)
		//err_sys("uname error");

	for ( hwa = Get_hw_addrs(); hwa != NULL; hwa = hwa->hwa_next) {

		if(strcmp(hwa->if_name,"eth0")==0){
		
			/* in eth0 we create pfsocket and bind it to hw addr, this pf socket is for sned ping info */
			//pf_sockfd = socket(PF_PACKET, SOCK_RAW,htons(ETH_P_IP));
			send_ping_pf_sockfd = socket(PF_PACKET, SOCK_RAW,htons(ETH_P_IP));
			//send_ping_pf_sockfd use to send ping to source node
			saddrll.sll_family      = PF_PACKET;
			saddrll.sll_ifindex     = hwa->if_index;
			saddrll.sll_protocol    = htons(ETH_P_IP); 
			bind(send_ping_pf_sockfd, (struct sockaddr *) &saddrll, sizeof(saddrll));
			
			
			printf("%s :%s", hwa->if_name, ((hwa->ip_alias) == IP_ALIAS) ? " (alias)\n" : "\n");
		
			if ( (sa = hwa->ip_addr) != NULL)
				printf("IP addr = %s\n", Sock_ntop_host(sa, sizeof(*sa)));
				
			prflag = 0;
			i = 0;
			do {
				if (hwa->if_haddr[i] != '\0') {
					prflag = 1;
					break;
				}
			} while (++i < IF_HADDR);

			if (prflag) {
				printf("         HW addr = ");
				ptr = hwa->if_haddr;
				i = IF_HADDR;
				do {
					printf("%.2x%s", *ptr++ & 0xff, (i == 1) ? " " : ":");
				} while (--i > 0);
			}
			printf("\n         Interface Index = %d\n\n", hwa->if_index);	
			break;
		}
		
	}
	
	
	/* creat two raw sockets for route travesal and receive ping*/

	rt_sockfd = Socket(AF_INET, SOCK_RAW, 254);
	setsockopt(rt_sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on));
	
	recv_ping_sockfd = Socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	setuid(getuid());           /* don't need special permissions any more */
	size = 60 * 1024;           /* OK if setsockopt fails */
	setsockopt (recv_ping_sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
		
	if (source_flag == 1)
	{//this node is source 

		struct icmp *icmp;
		struct ip* ip;
		int node_num;
		
		node_num = argc + 3;
		strcpy(tour_array[0], Sock_ntop_host(sa, sizeof(*sa)));//first one is source code

		sprintf(tour_array[1],"%d",argc - 1);
		sprintf(tour_array[2],"%d",node_num);
		sprintf(tour_array[3],"%d",4);
		for (i = 4; i < node_num; i++)
			strcpy(tour_array[i], getipbyvm(argv[i-3]));

//////////////////////////before send we let the source node join the multicast

		send_mulcst_fd = Udp_client(MC_ADDR_LIN, MC_PORT_LIN, (void **) &sasend, &salen);
		recv_mulcst_fd = Socket(AF_INET, SOCK_DGRAM, 0);
		Setsockopt(recv_mulcst_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
		sarecv = Malloc(salen);
		memcpy(sarecv, sasend, salen);
	
		Bind(recv_mulcst_fd, sarecv, salen);
		Mcast_join(recv_mulcst_fd, sasend, salen, NULL, 0);
		Mcast_set_loop(send_mulcst_fd, 0);
///////////////////////////////////////////////	this is the send tour part
	
		rt_send(rt_sockfd, tour_array);
	
		for(;;){
			if(first_mulcst_flag == 1){
				
				printf("wait for first multicast info\n");
				recv_all(recv_mulcst_fd, salen);
				first_mulcst_flag = 0;
				char buf[MAXLINE];
				//sleep(1);
				snprintf(buf, sizeof(buf), "<<<<< Node: %s I am a member of the group.>>>>>\n", myname.nodename);
				send_all(send_mulcst_fd, sasend, salen, buf);
				
			}else{
				for(;;){
					recv_all(recv_mulcst_fd, salen);
					printf("Waiting for 5 seconds and exit\n");
					
				}
			}
		}
			
	
			
		
		
		
	}else{//not source node
		pthread_t tid, tid2;
		char source_name[IPLEN];
		
		for( ;; )
		{
			FD_ZERO(&rset);
			
			FD_SET(rt_sockfd, &rset);
			
			
			maxfd = rt_sockfd;
			if(rt_recved_flag == 1){
				FD_SET(recv_ping_sockfd, &rset);
				maxfd = max(recv_ping_sockfd, maxfd);
			}
			
			if (ns_first_flag == 0)
			{
				FD_SET(recv_mulcst_fd,&rset);
				//maxfd = (maxfd > recv_mulcst_fd) ? maxfd : recv_mulcst_fd;
				maxfd = max(maxfd, recv_mulcst_fd);
			}
			
			//printf("before select\n");
			
			select(maxfd + 1, &rset, NULL, NULL, NULL);
			
			if (FD_ISSET(rt_sockfd, &rset)) 
			{    
				printf("receive route travelsal paket\n");
				n = rt_recv(rt_sockfd, tour_array);
				memcpy(dest_ip_addr, tour_array[0], IPLEN);
				if (n < 0) {
					if (errno == EINTR)
						continue;
				else
					err_sys("receive tour packet error");
				}
				
			    get_vmname(tour_array[0], source_name);
				
				
				 if (ns_first_flag == 1)
				{
					ns_first_flag = 0;
					rt_recved_flag = 1;
					
					// join the multicast first
					send_mulcst_fd = Udp_client(MC_ADDR_LIN, MC_PORT_LIN, (void **) &sasend, &salen);
					recv_mulcst_fd = Socket(AF_INET, SOCK_DGRAM, 0);
					Setsockopt(recv_mulcst_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
					sarecv = Malloc(salen);
					memcpy(sarecv, sasend, salen);
					Bind(recv_mulcst_fd, sarecv, salen);
					Mcast_join(recv_mulcst_fd, sasend, salen, NULL, 0);
					Mcast_set_loop(send_mulcst_fd, 0);
					
					//create a thread for ping
					Pthread_create(&tid, NULL, &ping, NULL);
						
				
				} 
				if(last_node_flag == 0){
					rt_send(rt_sockfd, tour_array);
				}else{
					//create a thread to handle last operations
					Pthread_create(&tid2, NULL, &ls_send_mul, &send_mulcst_fd);
				}
			}
			
			if (FD_ISSET(recv_mulcst_fd, &rset)) 
			{//recv multicast info
				if (first_mulcst_flag == 1 )
				{
					first_mulcst_flag = 0;
					ping_over_flag = 1;//
					//printf("ping_over_flag is %d\n", ping_over_flag);
					recv_all(recv_mulcst_fd, salen);
					char buf[MAXLINE];
					snprintf(buf, sizeof(buf), "<<<<< Node: %s I am a member of the group.>>>>>\n", myname.nodename);
					send_all(send_mulcst_fd, sasend, salen, buf); 
					//printf("gonna go to alarm with pof changed\n");
					alarm(0);
				
				}else{
						
						for(;;){
							recv_all(recv_mulcst_fd, salen);
						}
						printf("Waiting for 5 seconds and exit\n");
					}
				
			}
			
			 if (FD_ISSET(recv_ping_sockfd, &rset)) 
			{//recv ping reply
				//printf("received ping reply\n");
				recvfrom(recv_ping_sockfd, buff_recv, MAXLINE, 0, NULL, NULL);
				Gettimeofday (&tval, NULL);
				proc_v4 (buff_recv, n, &tval);
				if (ping_over_flag == 1)
					alarm(0);
			} 	
				
		}
	}
	

}
Пример #20
0
int start_server(const char *url, const char *rtspport)
{
  int mediafd = -1, listenfd, tempfd, maxfd;
  int videofd;
  struct addrinfo *info;
  struct sockaddr_storage remoteaddr;
  socklen_t addrlen = sizeof remoteaddr;
  fd_set readfds, masterfds;
  int nready, i;
  int videosize, videoleft;
  int recvd, sent;
  char urlhost[URLSIZE], urlpath[URLSIZE], tempstr[URLSIZE];
  unsigned char msgbuf[BUFSIZE], sendbuf[BUFSIZE];
  char *temp;
  RTSPMsg rtspmsg;
  Client streamclient;


  /* The current state of the protocol */
  int mediastate = IDLE;
  int quit = 0;

  init_client(&streamclient);

  /* Open the a file where the video is to be stored */
  if ((videofd = open("videotemp.mp4", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
    fatal_error("Error opening the temporary videofile");
  }

  /* Create the RTSP listening socket */
  resolve_host(NULL, rtspport, SOCK_STREAM, AI_PASSIVE, &info);
  listenfd = server_socket(info);
  maxfd = listenfd;


  FD_ZERO(&readfds);
  FD_ZERO(&masterfds);
  FD_SET(listenfd, &masterfds);


  while (!quit) {

    readfds = masterfds;

    if ((nready = Select(maxfd + 1, &readfds, NULL)) == -1) {
      write_log(logfd, "Select interrupted by a signal\n");
    } 

    for (i = 0; i <= maxfd; i++) {
      if (FD_ISSET(i, &readfds)) {

        nready--;

        /* New connection from a client */
        if (i == listenfd) {
          if ((tempfd = accept(i, (struct sockaddr *)&remoteaddr, &addrlen)) == -1) {
            if (errno != EWOULDBLOCK && errno != ECONNABORTED &&
                errno != EPROTO && errno != EINTR)
            {
              fatal_error("accept");
            }
          }

          /* If we are already serving a client, close the new connection. Otherwise, continue. */
          if (streamclient.state != NOCLIENT) close (tempfd);
          else {
            streamclient.rtspfd = tempfd;
            streamclient.state = CLICONNECTED;
            maxfd = max(2, streamclient.rtspfd, maxfd);
            FD_SET(streamclient.rtspfd, &masterfds);
          }
        }

        /* Data from the media source */
        else if (i == mediafd) {

          switch (mediastate) {

            case GETSENT:
              /* Read ONLY the HTTP message from the socket and store the video size */
              recvd = recv_all(i, msgbuf, BUFSIZE, MSG_PEEK);
              temp = strstr((char *)msgbuf, "\r\n\r\n");
              recvd = recv_all(i, msgbuf, (int)(temp + 4 - (char *)msgbuf), 0);
              temp = strstr((char *)msgbuf, "Content-Length:");
              sscanf(temp, "Content-Length: %d", &videosize);
              videoleft = videosize;
              mediastate = RECVTCP;
              break;

            case RECVTCP:
              if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
                FD_CLR(i, &masterfds);
                close(i);
                printf("Socket closed\n");
              }
              writestr(videofd, msgbuf, recvd);
              videoleft -= recvd;
              if (videoleft <= 0) mediastate = STREAM;
              break;

              /* TODO: Start streaming, currently just exits the program */
            case STREAM:
              /*
                 close(videofd);
                 close(mediafd);
                 close(listenfd);
                 quit = 1;
                 */
              break;

            default: 
              break;
          }
        }

        /* Data from a client ( i == streamclient.rtspfd) */
        else {

          if ((recvd = recv_all(i, msgbuf, BUFSIZE, 0)) == 0) {
            FD_CLR(i, &masterfds);
            close(i);
            printf("Socket closed\n");
            streamclient.state = NOCLIENT;
          }
          else {
            printf("%s", msgbuf);
            parse_rtsp(&rtspmsg, msgbuf); 
          }

          switch (streamclient.state) {

            case CLICONNECTED:
              if (rtspmsg.type == OPTIONS) {
                sent = rtsp_options(&rtspmsg, sendbuf);
                send_all(i, sendbuf, sent);
              }
              else if (rtspmsg.type == DESCRIBE) {

                /* Start fetching the file from the server */
                parse_url(url, urlhost, urlpath);
                resolve_host(urlhost, "80", SOCK_STREAM, 0, &info);
                mediafd = client_socket(info, 0);
                FD_SET(mediafd, &masterfds);
                maxfd = max(2, maxfd, mediafd);

                /* Send the GET message */
                http_get(url, msgbuf);
                send_all(mediafd, msgbuf, strlen((char *)msgbuf));
                mediastate = GETSENT;

                /* TODO: parse SDP from the media file rather than hardcoding it */
                sent = rtsp_describe(&rtspmsg, sendbuf);
                send_all(i, sendbuf, sent);
                streamclient.state = SDPSENT;
              }
              break;

            case SDPSENT:
              if (rtspmsg.type == SETUP) {
                sent = rtsp_setup(&rtspmsg, sendbuf, 50508, 50509);
                send_all(i, sendbuf, sent);
                write_remote_ip(tempstr, streamclient.rtspfd);
                resolve_host(tempstr, rtspmsg.clirtpport, 0, SOCK_DGRAM, &info); 
                streamclient.videofds[0] = client_socket(info, 50508);
                resolve_host(tempstr, rtspmsg.clirtcpport, 0, SOCK_DGRAM, &info);
                streamclient.videofds[1] = client_socket(info, 50509);
                streamclient.state = SETUPSENT;
              }
              break;

            case SETUPSENT:
              if (rtspmsg.type == PLAY) {
              }
              
              break;

            default:
              break;
          }
        }
      }
      if (nready <= 0) break;   
    }

  }


  return 1;
}
Пример #21
0
static bool send_size(int fd, size_t size)
{
    uint32_t size32 = ntohl(size);
    return send_all(fd, PS(size32));
}
Пример #22
0
int main(int argc, char **argv)
{
    int					sendfd, recvfd;
    const int			on = 1;
    socklen_t			salen;
    struct sockaddr		*sasend, *sarecv;
    int                 result;
    int                 onoff = 0;

    if (argc != 3) {
        printf("usage: ./multicasting <IP-multicast-address> <port#> <>");
        exit(1);
    }

    sendfd = udp_sender(argv[1], argv[2], &sasend, &salen);

    recvfd = socket(sasend->sa_family, SOCK_DGRAM, 0);
    assert(recvfd > 2);



    // Now IP from iface
//    int fd;
//     struct ifreq ifr;
//     fd = socket(AF_INET, SOCK_DGRAM, 0);
//     /* I want to get an IPv4 IP address */
//     ifr.ifr_addr.sa_family = AF_INET;
//     /* I want IP address attached to "eth0" */
//     strncpy(ifr.ifr_name, "enp0s25", IFNAMSIZ-1);
//     ioctl(fd, SIOCGIFADDR, &ifr);
//     close(fd);


     /* display result */
     //printf("%s\n", inet_ntoa( ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr) );

     // I don't want default iface but wlo1




    result = setsockopt(recvfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
    assert(result >= 0);

    sarecv = malloc(salen);
    assert(sarecv != NULL);

    memcpy(sarecv, sasend, salen);
    result = bind(recvfd, sarecv, salen);
    assert(result >= 0);

    char *src_host = sock_ntop(sarecv);
    printf("src_host = %s\n", src_host);
    char *dst_host = sock_ntop(sasend);
    printf("dst_host = %s\n", dst_host);

    result = mcast_join(recvfd, sasend, salen);
    assert(result >= 0);

    result = setsockopt(sendfd, IPPROTO_IP, IP_MULTICAST_LOOP,
                              &onoff, sizeof(onoff));
    assert(result >= 0);


//    struct in_addr interface_addr;// = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
//    interface_addr.s_addr = htonl(IP_SRC_ADDR_ENP);
//    result = setsockopt(recvfd, IPPROTO_IP, IP_MULTICAST_IF, &interface_addr, sizeof(interface_addr));
//    assert(result >= 0);


    if (fork() == 0)
        recv_all(recvfd, salen);

    send_all(sendfd, sasend, salen);
    return 0;
}
Пример #23
0
static void netplay_pre_frame_spectate(netplay_t *handle)
{
   unsigned i;
   if (handle->spectate_client)
      return;

   fd_set fds;
   FD_ZERO(&fds);
   FD_SET(handle->fd, &fds);

   struct timeval tmp_tv = {0};
   if (select(handle->fd + 1, &fds, NULL, NULL, &tmp_tv) <= 0)
      return;

   if (!FD_ISSET(handle->fd, &fds))
      return;

   struct sockaddr_storage their_addr;
   socklen_t addr_size = sizeof(their_addr);
   int new_fd = accept(handle->fd, (struct sockaddr*)&their_addr, &addr_size);
   if (new_fd < 0)
   {
      RARCH_ERR("Failed to accept incoming spectator.\n");
      return;
   }

   int index = -1;
   for (i = 0; i < MAX_SPECTATORS; i++)
   {
      if (handle->spectate_fds[i] == -1)
      {
         index = i;
         break;
      }
   }

   // No vacant client streams :(
   if (index == -1)
   {
      close(new_fd);
      return;
   }

   if (!get_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to get nickname from client.\n");
      close(new_fd);
      return;
   }

   if (!send_nickname(handle, new_fd))
   {
      RARCH_ERR("Failed to send nickname to client.\n");
      close(new_fd);
      return;
   }

   size_t header_size;
   uint32_t *header = bsv_header_generate(&header_size, implementation_magic_value());
   if (!header)
   {
      RARCH_ERR("Failed to generate BSV header.\n");
      close(new_fd);
      return;
   }

   int bufsize = header_size;
   setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsize, sizeof(int));

   if (!send_all(new_fd, header, header_size))
   {
      RARCH_ERR("Failed to send header to client.\n");
      close(new_fd);
      free(header);
      return;
   }

   free(header);
   handle->spectate_fds[index] = new_fd;

#ifndef HAVE_SOCKET_LEGACY
   log_connection(&their_addr, index, handle->other_nick);
#endif
}
Пример #24
0
/* borrowed from qemu-char.c */
static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len)
{
    return send_all(fd, buf, len);
}
Пример #25
0
	long Socket::send(const void *buf, const size_t length) const noexcept {
		return send_all(this->socket_handle, buf, length);
	}
Пример #26
0
void phone(void *vs){
	int* ps = (int *)vs;
	int s = *ps;
	FILE *fp_rec;
	FILE *fp_play;
	if ( (fp_rec=popen("rec -q -t raw -b 16 -c 1 -e s -r 44100 - 2> /dev/null","r")) ==NULL) {
		die("popen:rec");
	}
	if ( (fp_play=popen("play -t raw -b 16 -c 1 -e s -r 44100 - 2> /dev/null ","w")) ==NULL) {
		die("popen:play");
	}

	int cut_low=300, cut_high=5000;
	int send_len = (cut_high-cut_low)*N/SAMPLING_FREQEUENCY;
	sample_t * rec_data = malloc(sizeof(sample_t)*N);
	double * window_data = malloc(sizeof(double)*N);
	double * send_data = malloc(sizeof(double)*send_len*2);
	double * recv_data = malloc(sizeof(double)*send_len*2);
	sample_t * play_data = malloc(sizeof(sample_t)*N);
	sample_t * pre_data = malloc(sizeof(sample_t)*N/2);
	complex double * X = calloc(sizeof(complex double), N);
	complex double * Y = calloc(sizeof(complex double), N);
	complex double * Z = calloc(sizeof(complex double), N);
	complex double * W = calloc(sizeof(complex double), N);

	sample_t re=0, r;
	// time_t pre,now,mem;
	int i;
	memset(rec_data,0,N);
	memset(pre_data,0,N);
	// printf("phone\n");
	while(1){
		// printf("phone loop\n");
		// 必ずNバイト読む
		re = 0;
		// オーバーラップ
		while(re<N/2){
			r=fread(rec_data+N/2,sizeof(sample_t),N/2-re,fp_rec);
			if(r==-1) die("fread");
			if(r==0) break;
			re += r;
		}
		memset(rec_data+N/2+re,0,N/2-re);


		// 窓関数(ハミング窓)
		for (i = 0; i < N; ++i)	{
			window_data[i] = (0.54-0.46*cos(2*M_PI*i/(double)(N-1)))*rec_data[i];
		}
		memcpy(rec_data,rec_data+N/2,sizeof(sample_t)*N/2);

		// 複素数の配列に変換
		sample_to_complex_double(window_data, X, N);
		// /* FFT -> Y */
		fft(X, Y, N);
		// Yの一部を送る
		for(i=0;i<send_len;i++){
			send_data[2*i]=(double)creal(Y[cut_low*N/SAMPLING_FREQEUENCY+i]);
			send_data[2*i+1]=(double)cimag(Y[cut_low*N/SAMPLING_FREQEUENCY+i]);
		}
		// printf("s in phone: %d\n", s);
		if(send_all(s,(char *)send_data,sizeof(double)*send_len*2)==-1){
			die("send");
		}

		memset(W,0.0+0.0*I,N*sizeof(complex double));
		memset(Z,0.0+0.0*I,N*sizeof(complex double));
		// memset(rec_data,0,sizeof(long)*send_len*2);
		if(recv_all(s,(char *)recv_data,sizeof(double)*send_len*2)==-1){
			die("recv");
		}
		for(i=0; i<send_len; i++){
			W[cut_low*N/SAMPLING_FREQEUENCY+i]=(double)recv_data[2*i]+(double)recv_data[2*i+1]*I;
		}
		// /* IFFT -> Z */
		ifft(W, Z, N);

		// // 標本の配列に変換
		complex_to_sample(Z, play_data, N);
				// オーバーラップを戻す
		for(i=0;i<N/2;i++){
			play_data[i] += pre_data[i];
		}
		memcpy(pre_data,play_data+N/2,N/2);
		// 無音状態だったらスキップ
		int num_low=0;
		for(i=0;i<N;i++){
			if(-10<play_data[i] && play_data[i]<10)
				num_low++;
		}
		if(num_low>80*N/100)
			continue;
		// /* 標準出力へ出力 */
		// write(1,play_data,N/2);
		fwrite(play_data,sizeof(sample_t),N/2,fp_play);
	}
}
Пример #27
0
int main( int argc, char* argv[]){

	s_init();
	
	char port[5];
	if(argc >= 2)
		strcpy(port,argv[1]);
	else
	{
		printf("no se ingreso puerto del servidor, saliendo\n");
		return 0;
	}
    
    const struct socket_info server = server_connection_setup(atoi(port));

	if( server.error > 0)
	{
		printf("Error al configurar el socket\n");
        
		return 0;
	}
    
    printf("\nSocket configurado con exito\n");
    
     uint8_t vel = 80;
          uint8_t *velp = &vel;
    
    for(;;)
    {
		  struct socket_info client = server_connection_accept( server.socket);

		  printf("Conección aceptada : %#x.\n", client.socket_Addr.sin_addr.s_addr);
    
      for(;;)
      {
          //char send_buffer[100]="mensaje idle";//strlen( idle_msg)
          char recv_buffer, last_char=' ';
        
          if( recv( client.socket, &recv_buffer, 1, 0) <= 0)
          {
              connection_was_closed();
                
              break;
          }
        
          printf("Recibido: %c\n", recv_buffer);

         
          switch(recv_buffer)
          {
			case 'w':
			{
				char go[]="avanzando";
				send_all( client.socket, go, SEND_LENGTH, 0);
				s_send('w', vel);
				last_char = 'w';
				break;
			}
			case 'a':
			{
				char left[]="girando a la izquierda";
				send_all( client.socket, left, SEND_LENGTH, 0);
				s_send('a', vel);
				last_char = 'a';
				break;
			}
			case 's':
			{
				char back[]="retrocediendo";
				send_all( client.socket, back, SEND_LENGTH, 0);
				s_send('s', vel);
				last_char = 's';
				break;
			}
			case 'd':
			{
				char right[]="girando a la derecha";
				send_all( client.socket, right, SEND_LENGTH, 0);
				s_send('d', vel);
				last_char = 'd';
				break;
			}
			case '.':
			{
				char brake[]="acelerando";
				send_all( client.socket, brake, SEND_LENGTH, 0);
				*velp = (vel == 100)? vel: vel+10;
				s_send(last_char, vel);
				break;
			}
			case ',':
			{
				char brake[]="frenado";
				send_all( client.socket, brake, SEND_LENGTH, 0);
				*velp = (vel == 0)? vel: vel-10;
				s_send(last_char, vel);
				break;
			}
			default:
			{
				char nada[]="cualquier cosa";
				send_all( client.socket, nada, SEND_LENGTH, 0);
				s_send('l', vel);
				break;
			}
		   }
			

          /*if( send_all( client.socket, send_buffer, strlen( send_buffer), 0) <= 0)
          {
              connection_was_closed();
            
              break;
          }*/
      }
      
    }
    
    close( server.socket);//error: a label can only be part of a statement and a declaration is not a statement

	return 0;
}
Пример #28
0
void Sender::Impl::_send_packet(const lansink::Packet &_packet) {
    auto pBuf = std::unique_ptr<char[]>(new char[m_pPlug->nMTU]);
    assert(_packet.ByteSize() <= m_pPlug->nMTU);
    _packet.SerializeToArray((void *)pBuf.get(), m_pPlug->nMTU);
    send_all(m_nSocket, pBuf.get(), _packet.ByteSize(), 0);
}
Пример #29
0
int cmd_check(char* buffer,User* user){
  int ret;
  int descriptor= user->socket;
  if(strcmp(buffer,QUIT_COMMAND)==0){

    if(user->user_channel==NULL){
      char buffer[BUFFER_SIZE];
      snprintf(buffer,sizeof(buffer),"%s",QUIT_CLIENT);
      send_message(user->socket,buffer,strlen(buffer));
      return QUIT_RET;
    }

    Channel* desc_channel= user->user_channel;

    if(num_channels>0){
      if(isAdmin(descriptor,desc_channel)){
        if(desc_channel->sub_num>1){
          char buffer[BUFFER_SIZE];
          snprintf(buffer,sizeof(buffer),"%s","Do you want to close the channel? (y/n)");
          do{
            ret= send_message(descriptor,buffer,strlen(buffer));
            ret= receive_message(descriptor,buffer);
            if(strlen(buffer)==1){
              if(buffer[0]=='y'){
                delete_channel(desc_channel,descriptor);
                printf("Client disconnesso\n");
                return QUIT_RET;
              }
              else if(buffer[0]=='n') break;
            }
            memset(buffer,0,sizeof(buffer));
            snprintf(buffer,sizeof(buffer),"%s","Invalid input: choose between y or n!\n");
          }while(1);

        }
        else {
          char buffer[BUFFER_SIZE];
          snprintf(buffer,sizeof(buffer),"%s","You're the last active member. If you leave, the chat will be closed.\nDo you want to exit anyway? (y/n)\n");
          do{
            ret= send_message(descriptor,buffer,strlen(buffer));
            ret= receive_message(descriptor,buffer);
            if(strlen(buffer)==1){
              if(buffer[0]=='y'){
                delete_channel(desc_channel,descriptor);
                return QUIT_RET;
              }
              else if(buffer[0]=='n'){
                snprintf(buffer,sizeof(buffer),"%s","You're still in the chat.\n");
                send_message(descriptor,buffer,strlen(buffer));
                return 0;
              }
            }
            snprintf(buffer,sizeof(buffer),"%s","Invalid input: choose between y or n!\n");
          }while(1);
        }
      }
      delete_user_from_channel(descriptor,desc_channel);
      char buff_leave[BUFFER_SIZE];
      snprintf(buff_leave,sizeof(buff_leave),"%s","leave the chat");
      send_all(desc_channel,user,buff_leave);
      }
      send_message(descriptor,QUIT_CLIENT,strlen(QUIT_CLIENT));
      printf("Client disconnesso\n");
      return QUIT_RET;
    }
  return -1;
}
Пример #30
0
void fm_server_run(fm_server_t *server, server_handle handle, void *handle_data)
{
    int i;
    int client;
    char input_buf[64];
    char output_buf[1024];
    int buf_size;
    fd_set read_fds;
    char ipstr[INET6_ADDRSTRLEN];
    int port;

    while (!server->should_quit) {
        read_fds = server->fds;
        if (select(server->fd_max + 1, &read_fds, NULL, NULL, NULL) < 0) {
            if (errno == EINTR) {
                continue;
            }
            else {
                perror("select");
                return;
            }
        }

        if (FD_ISSET(server->listen_fd, &read_fds)) {
            client = accept(server->listen_fd, NULL, NULL);
            if (client < 0) {
                perror("accept");
            }
            else {
                getPeerInfo(client, ipstr, sizeof(ipstr), &port);
                printf("Server has a new client from %s:%d\n", ipstr, port);
                FD_SET(client, &server->fds);
                if (client > server->fd_max) {
                    server->fd_max = client;
                }
            }
            FD_CLR(server->listen_fd, &read_fds);
        }

        for (i = 0; i <= server->fd_max; i++) {
            if (FD_ISSET(i, &read_fds)) {
                memset(input_buf, 0, sizeof(input_buf));
                buf_size = recv(i, input_buf, sizeof(input_buf), 0);
                if (buf_size == 0) {
                    getPeerInfo(client, ipstr, sizeof(ipstr), &port);
                    printf("Server says goodbye to client from %s:%d\n", ipstr, port);
                    close(i);
                    FD_CLR(i, &server->fds);
                }
                else if (buf_size > 0) {
                    trim(input_buf);
                    getPeerInfo(client, ipstr, sizeof(ipstr), &port);
                    printf("Server receives from client %s:%d => %s\n", ipstr, port, input_buf);
                    memset(output_buf, 0, sizeof(output_buf));
                    handle(handle_data, input_buf, output_buf);
                    buf_size = strlen(output_buf);
                    if (send_all(i, output_buf, buf_size) < 0) {
                        perror("client write");
                        close(i);
                        FD_CLR(i, &server->fds);
                    }
                }
                else if (errno != EINTR) {
                    perror("client read");
                    close(i);
                    FD_CLR(i, &server->fds);
                }
            }
        }
    }
    for (i = 0; i <= server->fd_max; i++) {
        if (FD_ISSET(i, &server->fds)) {
            close(i);
        }
    }
}