Пример #1
0
/* ***************************************************
 * Function: send_syn_ack
 * ***************************************************
 * Passive node calls this to send SYN_ACK and wait for
 * the final ACK packet. It tries a total of 6 times before
 * giving up.
 */
static bool send_syn_ack(mysocket_t sd, context_t *ctx, struct tcphdr* syn_packet)
{
	struct tcphdr* ack_packet = (struct tcphdr *)calloc(1,(TH_MAX_OFFSET*sizeof(uint32_t))+STCP_MSS);
	unsigned int event;
	bool success = false;
	int num_tries = 1;
	struct timeval tstart;
	gettimeofday(&tstart, NULL); /*Start the timer */
	network_send(sd, syn_packet, (TH_MIN_OFFSET*sizeof(uint32_t)));
	while((num_tries < MAX_RT_TRIES) && !success){
		event = wait_for_event(sd, NETWORK_DATA, ctx, tstart);
		if (event & NETWORK_DATA) {
			network_recv(sd, ack_packet);
			our_dprintf("Passive (ACK waiting): Ack: %d, Seq:%d, Next Seq:%d, Last Ack Sent: %d\n", 
						 ack_packet->th_ack, ack_packet->th_seq, ctx->nxt_seq_num, ctx->last_ack_sent);
			success =  ((ack_packet->th_flags == TH_ACK) &&
						(ack_packet->th_ack == ctx->nxt_seq_num));
		}
		else if (event==TIMEOUT){
			our_dprintf("Passive Final INIT ACK not Received TIMEOUT!\n");	
			num_tries+=1;
			gettimeofday(&tstart, NULL);
			our_dprintf("PASSIVE - SEND SYN_ACK Packet with seq: %d and ack: %d \n",
						 syn_packet->th_seq, syn_packet->th_ack);
			network_send(sd, syn_packet, (TH_MIN_OFFSET*sizeof(uint32_t)));
		}
	}
	if (success){
		our_dprintf("PASSIVE - RCVD Last Ack Packet has seq: %d and ack: %d \n",
					 ack_packet->th_seq, ack_packet->th_ack);
   		ctx->recv_win = MIN(syn_packet->th_win, CWIN);
	}	
	free(ack_packet);
	return success;
}
Пример #2
0
/* ***************************************************
 * Function: passive_init
 * ***************************************************
 * Passive node waits for a SYN packet to arrive, it then
 * sends an SYN_ACK using another helper function (below)
 */
static bool passive_init(mysocket_t sd, context_t *ctx)
{
	ctx->connection_state = CSTATE_LISTEN;
	struct tcphdr* syn_packet = (struct tcphdr *)calloc(1,
				(TH_MAX_OFFSET*sizeof(uint32_t))+STCP_MSS);
   /* Listen for a connection request */
	while (true){
		stcp_wait_for_event(sd, NETWORK_DATA, NULL);
 		network_recv(sd, syn_packet);
		if (syn_packet->th_flags == TH_SYN){
			break;	
		}
	}
	our_dprintf("PASSIVE - RCVD SYN with seq: %d\n", syn_packet->th_seq);
	
	/* Prepare SYN_ACK*/			
	syn_packet->th_ack = syn_packet->th_seq + 1;
	syn_packet->th_seq = ctx->initial_sequence_num;
	syn_packet->th_off = TH_MIN_OFFSET;
	syn_packet->th_flags = TH_SYN | TH_ACK;
	syn_packet->th_win = RWIN;
	/*Update connection state variables */	
	ctx->last_ack_sent = syn_packet->th_ack;
	ctx->nxt_seq_num = ctx->initial_sequence_num + 1;
	ctx->connection_state = CSTATE_SYN_RCVD;
	ctx->seq_base = ctx->nxt_seq_num; 
	our_dprintf("PASSIVE - SEND SYN_ACK Packet with seq: %d and ack: %d \n",
				 syn_packet->th_seq, syn_packet->th_ack);
	bool success = send_syn_ack(sd, ctx, syn_packet);

	free(syn_packet);
	return success;
}
Пример #3
0
static ssize_t read_all(void *dst, size_t len, int fd)
{
	uintptr_t ptr = (uintptr_t) dst;
	while (len) {
		ssize_t ret = network_recv(fd, (void *) ptr, len, 0);
		if (ret < 0)
			return ret;
		ptr += ret;
		len -= ret;
	}
	return (ssize_t)(ptr - (uintptr_t) dst);
}
Пример #4
0
static ssize_t network_read_line(struct iio_context_pdata *pdata,
		int desc, char *dst, size_t len)
{
	size_t i;
#ifdef __linux__
	ssize_t ret;

	ret = network_recv(desc, dst, len, MSG_PEEK);
	if (ret < 0)
		return ret;

	/* Lookup for the trailing \n */
	for (i = 0; i < (size_t) ret && dst[i] != '\n'; i++);

	/* No \n found? Just garbage data */
	if (i == (size_t) ret)
		return -EIO;

	/* Advance the read offset to the byte following the \n */
	return network_recv(desc, dst, i + 1, MSG_TRUNC);
#else
	bool found = false;

	for (i = 0; i < len - 1; i++) {
		ssize_t ret = network_read_data(pdata, desc, dst + i, 1);

		if (ret < 0)
			return ret;

		if (dst[i] != '\n')
			found = true;
		else if (found)
			break;
	}

	dst[i] = '\0';
	return (ssize_t) i;
#endif
}
Пример #5
0
gpointer
network_reciever(gpointer data)
{
	char *buffer;
	unsigned int level;
	sys_queue = g_async_queue_new();
	msg_queue = g_async_queue_new();
	pthread_detach(pthread_self());
	while (1) {
		if (network_recv(&level, (void **)buffer, security->session) < 1)
			break;
		if (level == PACKET_SYS)
			g_async_queue_push(sys_queue, buffer);
		else if (level == PACKET_MSG)
			g_async_queue_push(msg_queue, buffer);
		else
			printf("Cannot specify target for packet(not sys and msg).\n");
	}
	
}
Пример #6
0
void NetworkWorker::run()
{
  while (true)
    {
      {
	Glib::Threads::Mutex::Lock lock(m_mutex);
	if (m_network.disconnected)
	  break;
	network_set_fds(&m_network);
	m_network.tv.tv_sec = 1;
	m_network.tv.tv_usec = 0;	
      }
      network_select(&m_network);
      {
	Glib::Threads::Mutex::Lock lock(m_mutex);
	network_recv(&m_network);
	network_send(&m_network);
	m_stop = m_network.disconnected;
	if (m_network.has_data_in)
	  {
	    std::string data(m_network.buf_in);
	    m_network.buf_in[0] = 0;
	    m_network.has_data_in = FALSE;
	    int pos;
	    while ((pos = data.find("\r\n")) != std::string::npos)
	      {
		m_in_data.push(data.substr(0, pos));
		data = data.substr(pos + 2);
	      }
	    strcpy(m_network.buf_in, data.c_str());
	    strcat(m_network.buf_in, "\0");
	    if (strlen(m_network.buf_in) > 0)
	      m_network.has_data_in = TRUE;
	  }	
      }
      {
	Glib::Threads::Mutex::Lock lock(m_mutex);
	m_dispatcher.emit();
      }
    }
}
Пример #7
0
/* ***************************************************
 * Function: sendrcv_syn
 * ***************************************************
 * 	Helper function for active-side network initiation.
 *   It sends the SYN packet and waits for the right SYN_ACK
 */
static bool sendrcv_syn(mysocket_t sd, context_t *ctx, struct tcphdr* in_packet)
{
	/* Set SYN Headers */
	struct tcphdr* out_packet = (struct tcphdr *)calloc(1,(TH_MIN_OFFSET*sizeof(uint32_t)));
	out_packet->th_ack = 0; 
	out_packet->th_seq = ctx->initial_sequence_num;
  	out_packet->th_flags = TH_SYN;
	out_packet->th_off = TH_MIN_OFFSET;
	out_packet->th_win = RWIN;
	ctx->nxt_seq_num = ctx->initial_sequence_num + 1; /* SYN Packet =  1 byte */
	our_dprintf("Active Sending SYN.  Seq:%d\n", out_packet->th_seq);
	
	unsigned int event;
	bool success = false;
	int num_tries = 1;
	struct timeval tstart;
	gettimeofday(&tstart,NULL); /*start the timer */
	network_send(sd, out_packet, (TH_MIN_OFFSET*sizeof(uint32_t)));
	/* Try sending the SYN a total of 6 times before giving up */
	while ((num_tries < MAX_RT_TRIES) && !success){
		event = wait_for_event(sd, NETWORK_DATA, ctx, tstart);
		if (event & NETWORK_DATA) {
			network_recv(sd, in_packet);
			/* Check to see if we got the right SYN_ACK */
			success = ((in_packet->th_flags & (TH_SYN | TH_ACK)) &&
			    	  (in_packet->th_ack == ctx->nxt_seq_num));
		}
		else if (event==TIMEOUT){
			our_dprintf("Active - SYN TIMEOUT!, no SYN_ACK!\n");
			gettimeofday(&tstart,NULL);
			num_tries+=1;
			our_dprintf("Active Resending SYN.  Seq:%d\n", out_packet->th_seq);
			network_send(sd, out_packet, (TH_MIN_OFFSET*sizeof(uint32_t)));
		}
	}	
	free(out_packet);
	return success;
}
Пример #8
0
/* ***************************************************
 * Function: handle_network_data
 * ***************************************************
 *  A packet has arrived.  If its an ACK packet, call a helper 
 * function that deals with acks.  If the packet has data or it's
 * a FIN packet, then add the packet to the receiver buffer only
 * if it fits in the receiving window.  If it doesn't fit,
 * drop the packet.  If it fits, send an acknowledgement.
 */
static void handle_network_data(mysocket_t sd, context_t *ctx)
{
	   char *pkt = (char *)calloc(1, (TH_MAX_OFFSET*sizeof(uint32_t)) + STCP_MSS);
	   size_t total_length = network_recv(sd, pkt);
	   struct tcphdr* hdr = (struct tcphdr *)pkt;
	   ctx->recv_win = MIN(hdr->th_win, CWIN);
	   if (hdr->th_flags & TH_ACK) {
			handle_ack(hdr, sd, ctx);
	   }
	   size_t data_length = total_length - TCP_DATA_START(hdr);
	   if (data_length>0 || (hdr->th_flags & TH_FIN)) {
	   		our_dprintf("Received %d bytes of data with seq: %d, last ack sent: %d\n", 
	   					data_length, hdr->th_seq, ctx->last_ack_sent);
	   		/* Does the packet fit in the receiving window?*/
	   		if ((hdr->th_seq + data_length)<=(ctx->last_ack_sent + RWIN)) {
	   			add_to_recv_buffer(ctx, pkt, total_length);
	   			if (hdr->th_seq == ctx->last_ack_sent){
	   				/* The packet arrived in order. We can remove all in-order
	   				 * packets from the receive buffer now */
	   				our_dprintf("Packet In Order. Handling buffer\n");
	   				handle_recv_buffer(sd, ctx);
	   			}
	   			else {
	   				if (hdr->th_seq > ctx->last_ack_sent) {
	   					our_dprintf("This packet is out of order. Adding to recv buffer\n");
	   				}
	   			}
	   			send_ack(sd, ctx);
	   		}
	   		else {
	   			our_dprintf("Packet outside receiver buffer. Dropping!!!\n");	
	   	
	   		}		
	   }
	   free(pkt);			
}
Пример #9
0
/**
 * Thread processing network events (coming from other nodes).
 *
 * This routine may set the network status to down as a side-effect
 * of calling network_recv(), and sets said status to up when the
 * network comes back.
 *
 * \param[in] dummy  Unused
 *
 * \return NULL
 */
static void
net_events_routine(void *dummy)
{
  int dest_mbox;
  ExamsgMID mid;
  size_t size;
  char *msg;
  int s;

  exalog_as(EXAMSG_CMSGD_ID);
  exalog_trace("network events routine started");

  while (!quit)
    {
      int status = network_status();
      bool retry;

      if (status == -ENETDOWN)
	{
	  network_waitup();
	  network_set_status(0);
	}

      do
	{
	  s = network_recv(net_mh, &mid, &msg, &size, &dest_mbox);
	  retry = (s < 0 && network_manageable(s) && s != -ENETDOWN);
	  if (retry)
	      os_sleep(1);
	}
      while (retry);

      /* Succeeded, the network status is ok */
      if (s > 0 && status != 0)
	network_set_status(0);

      if (s == 0 || s == -ENETDOWN)
	continue;

      EXA_ASSERT(s > 0);

      /* Ping from another node for keepalive */
      if (((ExamsgAny *)msg)->type == EXAMSG_PING)
	{
	  EXA_ASSERT(dest_mbox == EXAMSG_CMSGD_ID);
	  exalog_trace("received an EXAMSG_PING from %u:%s",
		       mid.netid.node, mid.host);
	  continue;
	}

      exalog_trace("delivering %" PRIzu " bytes to %d",
		   size, dest_mbox);

      s = examsgMboxSend(&mid, examsgOwner(net_mh), dest_mbox, msg, size);
      switch (s)
	{
	case -ENXIO:
         /* The mailbox does not exist (yet). This is not an error: csupd may
          * not be started yet and we receive an examsg for it.
          * XXX Doesn't sound too good to me, and we should at least check that
          * the destination is indeed csupd */
	  break;

	case -ENOSPC:
	  mailbox_full(dest_mbox, &mid, (Examsg *)msg);
	  break;

	default:
	  EXA_ASSERT_VERBOSE(s == size + sizeof(mid),
		             "Error %d delivering message to %d",
			     s, dest_mbox);
	  break;
	}
    }
}
Пример #10
0
static void client_console(int sock)
{
    char client_buf[BABBLE_BUFFER_SIZE];
    char *server_buf;

    char *user_buf =NULL;
    size_t user_buf_size=0;

    int cid = -1;
    int answer_expected = 0;
    
    
    while(getline(&user_buf, &user_buf_size, stdin) != -1){
        /* truncate input if need be */
        strncpy(client_buf, user_buf, BABBLE_BUFFER_SIZE);

        str_clean(client_buf);
        
        /* check command on client side */
        cid = str_to_command(client_buf, &answer_expected);
        
        if(cid == -1){
            continue;
        }
        
        if (network_send(sock, strlen(client_buf)+1,(void*) client_buf) != strlen(client_buf)+1){
            perror("ERROR writing to socket");
            break;
        }
        
        if(cid == TIMELINE){
            
            /* specific protocol for timeline request */
            int *t_length, i;
            if(network_recv(sock, (void**) &t_length) != sizeof(int)){
                perror("ERROR in timeline protocol");
                break;
            }

            printf("Timeline of size: %d\n", *t_length);

            /* recv only the last BABBLE_TIMELINE_MAX */
            int to_recv= (*t_length < BABBLE_TIMELINE_MAX)? *t_length :  BABBLE_TIMELINE_MAX;

            free(t_length);
            
            for(i=0; i< to_recv; i++){
                if(network_recv(sock, (void**) &server_buf) < 0){
                    perror("ERROR reading from socket");
                    break;
                }
                printf("%s", server_buf);
                free(server_buf);
            }

            if(i != to_recv){
                break;
            }
        }
        else{
            if(answer_expected){
                if(network_recv(sock, (void**) &server_buf) < 0){
                    perror("ERROR reading from socket");
                    break;
                }
                printf("%s", server_buf);
                free(server_buf);
            }
        }
        
    }

    printf("### Client exiting \n");
}
Пример #11
0
static ssize_t network_read_data(struct iio_context_pdata *pdata,
		int desc, char *dst, size_t len)
{
	return network_recv(desc, dst, len, 0);
}