Beispiel #1
0
/* Retransmit the last packet */
int resend_packet()
{
	void * packet;
	int len;
	struct radio_tap_header *rt_header;
	struct dot11_frame_header *frame_header;

	packet = get_last_packet(&len);
	rt_header = (struct radio_tap_header *) packet;
	frame_header = (struct dot11_frame_header *) (packet + rt_header->len);

	frame_header->fc.retry = 1;

	return send_packet(packet, len);
}
Beispiel #2
0
/* This is a receive function for the gnutls handshake 
 * protocol. Makes sure that we have received all data.
 */
ssize_t
_gnutls_handshake_io_recv_int (gnutls_session_t session,
                               gnutls_handshake_description_t htype,
                               handshake_buffer_st * hsk)
{
  int ret;

  ret = get_last_packet(session, htype, hsk);
  if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    {
      return gnutls_assert_val(ret);
    }

  /* try using the already existing records before
   * trying to receive.
   */
  ret = parse_record_buffered_msgs(session, htype, hsk);
  if (IS_DTLS(session))
    {
      if (ret >= 0)
        return ret;
    }
  else
    {
      if ((ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE && ret < 0) || ret >= 0)
        return gnutls_assert_val(ret);
    }

  /* if we don't have a complete message waiting for us, try 
   * receiving more */
  ret = _gnutls_recv_in_buffers(session, GNUTLS_HANDSHAKE, htype);
  if (ret < 0)
    return gnutls_assert_val_fatal(ret);

  return parse_record_buffered_msgs(session, htype, hsk); 
}
Beispiel #3
0
/* This is a receive function for the gnutls handshake 
 * protocol. Makes sure that we have received all data.
 */
ssize_t
_gnutls_handshake_io_recv_int(gnutls_session_t session,
			      gnutls_handshake_description_t htype,
			      handshake_buffer_st * hsk,
			      unsigned int optional)
{
	int ret;
	unsigned int tleft = 0;
	int retries = 7;

	ret = get_last_packet(session, htype, hsk, optional);
	if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED &&
	    ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE &&
	    ret != GNUTLS_E_INT_CHECK_AGAIN) {
		return gnutls_assert_val(ret);
	}

	/* try using the already existing records before
	 * trying to receive.
	 */
	ret = _gnutls_parse_record_buffered_msgs(session);

	if (ret == 0) {
		ret = get_last_packet(session, htype, hsk, optional);
	}

	if (IS_DTLS(session)) {
		if (ret >= 0)
			return ret;
	} else {
		if ((ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
		     && ret < 0) || ret >= 0)
			return gnutls_assert_val(ret);
	}

	if (htype != (gnutls_handshake_description_t) -1) {
		ret = handshake_remaining_time(session);
		if (ret < 0)
			return gnutls_assert_val(ret);
		tleft = ret;
	}

	do {
		/* if we don't have a complete message waiting for us, try 
		 * receiving more */
		ret =
		    _gnutls_recv_in_buffers(session, GNUTLS_HANDSHAKE, htype,
					    tleft);
		if (ret < 0)
			return gnutls_assert_val_fatal(ret);

		ret = _gnutls_parse_record_buffered_msgs(session);
		if (ret == 0) {
			ret = get_last_packet(session, htype, hsk, optional);
		}
		/* we put an upper limit (retries) to the number of partial handshake
		 * messages in a record packet. */
	} while(IS_DTLS(session) && ret == GNUTLS_E_INT_CHECK_AGAIN && retries-- > 0);

	if (unlikely(IS_DTLS(session) && ret == GNUTLS_E_INT_CHECK_AGAIN)) {
		ret = gnutls_assert_val(GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS);
	}

	return ret;
}
Beispiel #4
0
/*  up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT
 A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION.
 */
int up_to_network(char *packet, size_t length, int arrived_on_link) {
        NL_PACKET *p = (NL_PACKET *) packet;
	if(p->src == nodeinfo.address){
	  printf ("drop a packet at %d, src = %d, des = %d, seqno = %d\n", nodeinfo.address, p->src, p->dest, p->seqno);
	  return 0;
	}
	//printf("up to network at %d (from %d to %d)\n", nodeinfo.address, p->src, p->dest);
        ++p->hopcount; /* took 1 hop to get here */
        mtu = linkinfo[arrived_on_link].mtu;
        p->trans_time += ((CnetTime)8000 * 1000 * mtu / linkinfo[arrived_on_link].bandwidth + linkinfo[arrived_on_link].propagationdelay)*100/mtu;
        ////("me = %d, dest = %d =======\n", nodeinfo.address, p->dest);
        /*  IS THIS PACKET IS FOR ME? */
        if (p->dest == nodeinfo.address) {
                switch (p->kind) {
                case NL_DATA:
                        if (p->seqno == NL_packetexpected(p->src)) {
                                length = p->length;
                                memcpy(rb[p->src], (char *) p->msg, length);
                                rb[p->src] = rb[p->src] + length;
				//packet_length[p->src] += length;

                                if (p->pieceEnd) {
                                        CnetAddr tmpaddr;
                                        length = p->pieceNumber * (linkinfo[arrived_on_link].mtu
                                                        - PACKET_HEADER_SIZE) + p->length;
					//length = packet_length[p->src];
					//packet_length[p->src] = 0;
                                        int p_checksum = p->checksum;
                                        int checksum = CNET_ccitt(
                                                        (unsigned char *) (receiveBuffer[p->src]),
                                                        p->src_packet_length);
					if(p->is_resent){
					  printf("%d received a resent packet, src = %d, des = %d, seqno = %d,  send_length = %d,receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length);
					}else{
					  printf("%d received a packet, src = %d, des = %d, seqno = %d,  send_length = %d,receive_length = %d \n", nodeinfo.address, p->src, p->dest, p->seqno, p->src_packet_length, length);
					}

					printf("last_piece_trans_time = %d, hopcount = %d\n", p->trans_time, p->hopcount);
					printf("src_checksum = %d calc_checksum = %d, ", p_checksum, checksum);
                                        if (p_checksum != checksum) {
                                                /***************************send back error ack**************/
						printf("error packet\n\n");
                                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);

                                                tmpaddr = p->src; /* swap src and dest addresses */
                                                p->src = p->dest;
                                                p->dest = tmpaddr;
						
						if(p->is_resent == 1)
						    p->kind = NL_ERR_ACK_RESENT;
						  else
						    p->kind = NL_ERR_ACK;
						
						p->hopcount = 0;
						p->pieceNumber = 0;
						p->pieceEnd = 0;
						p->length = 0;
						p->src_packet_length = 0;
						p->checksum = 0;
						p->trans_time = 0;
						
                                                flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0);
                                                
                                                rb[p->src] = &receiveBuffer[p->src][0];
						//printf("\n");
                                                return 0;
                                                /***************************end******************************/
                                        }
                                        /*
                                        if (CNET_write_application(receiveBuffer[p->src], &length)
                                                        == -1) {
                                                //source node should send this msg again
                                                //printf("===\ncnet_errno = %d\n===\n", cnet_errno);
                                                //printf("error count: %d\n", ++ err_count);
                                                if (cnet_errno == ER_CORRUPTFRAME) {
						   printf("corrupt packet\n");
                                                        //printf("\nWarning: frame corrupted\n==\n");
                                                } else if (cnet_errno == ER_MISSINGMSG) {
						   printf("unordered packet\n");
                                                        //printf("\nWarning: frame missed\n\n");
                                                } else if(cnet_errno == ER_BADSIZE){
						  printf("loss packet\n");
						}
                                        }
                                        */
					CHECK(CNET_write_application(receiveBuffer[p->src], &length));
					printf("correct packet\n", p->dest, p->seqno, p->src);
                                        rb[p->src] = &receiveBuffer[p->src][0];

                                        inc_NL_packetexpected(p->src);

                                        NL_savehopcount(p->src, p->trans_time, arrived_on_link);

                                        tmpaddr = p->src; /* swap src and dest addresses */
                                        p->src = p->dest;
                                        p->dest = tmpaddr;

                                        p->kind = NL_ACK;
                                        p->hopcount = 0;
					p->pieceNumber = 0;
					p->pieceEnd = 0;
					p->length = 0;
					p->src_packet_length = 0;
					p->checksum = 0;
					p->trans_time = 0;
					p->is_resent = 0;
					
                                        flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0);
					printf("\n");
                                }
                        }
                        break;

                case NL_ACK:
                        if (p->seqno == NL_ackexpected(p->src)) {
                                ////("ACK come!\n");
                                inc_NL_ackexpected(p->src);
                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_set_has_resent(p->src, 0);
                                CHECK(CNET_enable_application(p->src));
                        }
                        break;
                case NL_ERR_ACK:
                        printf("NL_ERR_ACK!\n");
                        if (p->seqno == NL_ackexpected(p->src)){
			  if(NL_get_has_resent(p->src) == 0) {
                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);
                                NL_PACKET * packettoresend = get_last_packet(p->src);
                                printf("src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum);
				printf("resend it\n");
                                int len = PACKET_HEADER_SIZE + packettoresend->length;
				packettoresend->is_resent = 1;
				NL_set_has_resent(p->src, 1);
				NL_inc_resent_times(p->src); // for debug
                                flood3((char *) packettoresend, len, 0, 0);
                                
			  } else{
			      printf("this packet has already been resent, dont resent it again\n");
			  }
			} else{
			    printf("this packet has already been correct received, dont resent it again\n");
			}
                        printf("\n");
                        break;
		case NL_ERR_ACK_RESENT:
                        printf("NL_ERR_ACK_RESENT!\n");
                        if (p->seqno == NL_ackexpected(p->src)) {
                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);
                                NL_PACKET * packettoresend = get_last_packet(p->src);
                                printf("resend a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n", packettoresend->src, packettoresend->dest, packettoresend->seqno, packettoresend->length, packettoresend->checksum);
				printf("this packet has been resent %d times before this time\n", NL_get_resent_times(p->src)); //for debug
				NL_inc_resent_times(p->src); // for debug
                                int len = PACKET_HEADER_SIZE + packettoresend->length;
				packettoresend->is_resent = 1;
                                flood3((char *) packettoresend, len, 0, 0);
                                
                        } else{
			    printf("this packet has already been correct received, dont resent it again\n");
			}
                        printf("\n");
                        break;
                default:
                        //("it's nothing!====================\n");
                        break;
                }
        }
        /* THIS PACKET IS FOR SOMEONE ELSE */
        else {
                //              //("hopcount = %d\n", p->hopcount);
                //              //("MAXHOPS = %d\n", MAXHOPS);
                if (p->hopcount < MAXHOPS) { /* if not too many hops... */
                        ////("other's frame!\n");

                        //("piece for another node arrives\n");
                        length = p->length;
                        memcpy(rb[p->src], (char *) p->msg, length);
                        rb[p->src] = rb[p->src] + length;
			//packet_length[p->src] += length;

                        if (p->pieceEnd) {
                                //printf("last piece for another node arrives\n");
                                length = p->pieceNumber * (linkinfo[arrived_on_link].mtu
                                                - PACKET_HEADER_SIZE) + p->length;
				//length = packet_length[p->src];
				//packet_length[p->src] = 0;
                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);

                                NL_PACKET wholePacket;

                                wholePacket.src = p->src;
                                wholePacket.dest = p->dest;
                                wholePacket.kind = p->kind;
                                wholePacket.seqno = p->seqno;
                                wholePacket.hopcount = p->hopcount;
				wholePacket.pieceNumber = 0;
                                wholePacket.pieceEnd = 0;
				wholePacket.length = length;
				wholePacket.src_packet_length = p->src_packet_length;
				wholePacket.checksum = p->checksum;
				wholePacket.trans_time = p->trans_time;
				wholePacket.is_resent = p->is_resent;
				
				memcpy(wholePacket.msg, receiveBuffer[p->src], length);

                                //                             //("contents of msg forwarding is \n %s\n", receiveBuffer[p->src]);
                                flood3((char *) &wholePacket, PACKET_SIZE(wholePacket), 0,
                                                arrived_on_link);
                                rb[p->src] = &receiveBuffer[p->src][0];

                        }

                } 
                else {  /* silently drop */;
		  //free(&p->msg);
		  //free(p);
		}
        }
        return (0);
}
Beispiel #5
0
/*  up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT
 A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION.
 */
int up_to_network(char *packet, size_t length, int arrived_on_link) {

	NL_PACKET *p = (NL_PACKET *) packet;
	if (p->src == nodeinfo.address) {
		printf(
				"drop a packet at %d, src = %d, des = %d, seqno = %d, length = %d\n\n",
				nodeinfo.address, p->src, p->dest, p->seqno, p->length);
		return 0;
	}

	++p->hopcount; /* took 1 hop to get here */
	mtu = linkinfo[arrived_on_link].mtu;
	p->trans_time += ((CnetTime) 8000 * 1000 * mtu
			/ linkinfo[arrived_on_link].bandwidth
			+ linkinfo[arrived_on_link].propagationdelay) * 100 / mtu;

	size_t maxsize = mtu - PACKET_HEADER_SIZE;
	if (p->length > maxsize || p->length < (size_t) 0) {
		//fprintf(stdout, "p->length = %d, max size = %d\n", (int)(p->length), (int) maxsize);
		return 0;
	}
	CnetAddr tempaddr;
	/*  IS THIS PACKET IS FOR ME? */
	if (p->dest == nodeinfo.address) {

		switch (p->kind) {
		case NL_TEST:
			if (NL_gettesthascome(p->src))
				break;
			printf("test packet come!\n");
			NL_savehopcount(p->src, p->hopcount, arrived_on_link);
			NL_updateminmtu(p->src, p->min_mtu, arrived_on_link);
			NL_inctesthascome(p->src);

			tempaddr = p->src;
			p->src = p->dest;
			p->dest = tempaddr;

			p->kind = NL_TEST_ACK;
			p->hopcount = 0;
			p->length = 0;
			flood_test(packet, PACKET_HEADER_SIZE, arrived_on_link, 0);
			break;
		case NL_TEST_ACK:
			printf("test packet ack come!\n");
			NL_savehopcount(p->src, p->hopcount, arrived_on_link);
			NL_updateminmtu(p->src, p->min_mtu, arrived_on_link);
			break;

		case NL_DATA:

			if (p->seqno == NL_packetexpected(p->src)) {

				if (RB_save_msg_link(rb, p, arrived_on_link) == 2) {
					/*
					 all pieces are arrived
					 now get the whole msg from buffer and write it in applicaiton layer
					 */
					RB_copy_whole_msg_link(rb, p, arrived_on_link);
					CHECK(CNET_write_application((char*) p->msg,
							&p->src_packet_length));
					send_ack(p, arrived_on_link, 0);
					return 0;

				} else if (p->pieceEnd || p->is_resent) {
					/*
					 last piece arrives, now check the missing frame position
					 */

					// check which piece is missing and require to resend this piece

					//TODO: check which piece is missing
					//TODO: and require to resend this piece

				}
			}
			break;

		case NL_ACK:
			if (p->seqno == NL_ackexpected(p->src)) {
				printf("ACK come!\n");
				inc_NL_ackexpected(p->src);
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_set_has_resent(p->src, 0);
				NL_update_lastackexpected(p->src);
				CHECK(CNET_enable_application(p->src));
			} else if (p->seqno < NL_ackexpected(p->src)) {
				printf("outdated ACK come!\n");

			}
			break;
		case NL_ERR_ACK:
			printf("NL_ERR_ACK!\n");
			if (p->seqno == NL_ackexpected(p->src)) {
				if (NL_get_has_resent(p->src) == 0) {
					NL_savehopcount(p->src, p->trans_time, arrived_on_link);
					NL_PACKET * packettoresend = get_last_packet(p->src);
					printf(
							"src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n",
							packettoresend->src, packettoresend->dest,
							packettoresend->seqno, packettoresend->length,
							packettoresend->checksum);
					printf("resend it\n");
					int len = PACKET_HEADER_SIZE + packettoresend->length;
					packettoresend->is_resent = 1;
					NL_set_has_resent(p->src, 1);
					flood((char *) packettoresend, len, 0, 0);

				} else {
					printf(
							"this packet has already been resent, dont resent it again\n");
				}
			} else {
				printf(
						"this packet has already been correct received, dont resent it again\n");
			}
			break;

		case NL_ERR_ACK_RESENT:
			printf("NL_ERR_ACK_RESENT!\n");
			if (p->seqno == NL_ackexpected(p->src)) {
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_PACKET * packettoresend = get_last_packet(p->src);
				printf(
						"resend a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n",
						packettoresend->src, packettoresend->dest,
						packettoresend->seqno, packettoresend->length,
						packettoresend->checksum);

				int len = PACKET_HEADER_SIZE + packettoresend->length;
				packettoresend->is_resent = 1;
				flood((char *) packettoresend, len, 0, 0);

			} else {
				printf(
						"this packet has already been correct received, dont resent it again\n");
			}

			break;
		default:
			printf("it's nothing!====================\n");
			break;
		}
	}
	/* THIS PACKET IS FOR SOMEONE ELSE */
	else {
		if (p->kind == NL_TEST) {
			CnetAddr tmp;
			NL_PACKET temp_p;
			if (p->hopcount < MAXHOPS) {
				NL_savehopcount(p->src, p->hopcount, arrived_on_link);
				NL_updateminmtu(p->src, p->min_mtu, arrived_on_link);

				temp_p.src = p->src;
				temp_p.dest = p->dest;
				temp_p.min_mtu = p->min_mtu;
				temp_p.hopcount = p->hopcount;

				/* retransmit on best links *except* the one on which it arrived */

				if (NL_minmtu(temp_p.dest) != 0 && NL_minmtu(temp_p.dest) != -1) {

					if (temp_p.min_mtu > NL_minmtu(temp_p.dest)) {
						temp_p.min_mtu = NL_minmtu(temp_p.dest);
					}
					//temp_p.hopcount = NL_gethopcount(temp_p.src) + NL_gethopcount(
					//	temp_p.dest);
					temp_p.hopcount = NL_gethopcount(temp_p.dest);
					tmp = temp_p.dest;
					temp_p.dest = temp_p.src;

					temp_p.src = tmp;

					temp_p.kind = NL_TEST_ACK;
					temp_p.length = 0;
					printf("send query result of %d to %d, min_mtu = %d\n",
							temp_p.src, temp_p.dest, temp_p.min_mtu);
					flood_test((char *) &temp_p, PACKET_HEADER_SIZE,
							arrived_on_link, 0);
				}
			}
		}

		else if (p->hopcount < MAXHOPS) { /* if not too many hops... */

			NL_savehopcount(p->src, p->hopcount, arrived_on_link);//TODO: pay attention for this line, shall we need it?

			/* retransmit on best links *except* the one on which it arrived */
			flood(packet, length, 0, arrived_on_link);
		}
	}
	return 0;
}
Beispiel #6
0
/*  up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT
 A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION.
 */
int up_to_network(char *packet, size_t length, int arrived_on_link) {
	printf("up to network at hop %s \n", nodeinfo.nodename);
	NL_PACKET *p = (NL_PACKET *) packet;
	
	//if(p->traveled_hops_count < 1 || p->traveled_hops_count > MAXHOPS)
	  //return 0;
	
	//++p->hopcount; /* took 1 hop to get here */
	if(p->traveled_hops_count > 0 && p->traveled_hops_count<= MAXHOPS){
	  is_traveled_hop = 0;
	  for(i=0; i<p->traveled_hops_count; ++i){
	    if(p->traveled_hops[i] == nodeinfo.nodenumber){
	      is_traveled_hop = 1;
	      break;
	    }
	  }
	  if(is_traveled_hop != 1){
	    printf("seqno %d    pieceNumber %d   src %d    des %d    current_hop %d\n", p->seqno, p->pieceNumber, p->src, p->dest, nodeinfo.address);
	    printf("p->traveled_hops_count %d\n", p->traveled_hops_count);
	    p->traveled_hops[p->traveled_hops_count++] = nodeinfo.nodenumber;
	    mtu = linkinfo[arrived_on_link].mtu;
	    p->trans_time += ((CnetTime)8000000 * mtu / linkinfo[arrived_on_link].bandwidth + linkinfo[arrived_on_link].propagationdelay)/mtu;
	    //p->trans_time += linkinfo[arrived_on_link].costperframe;
	  } else{ 
	      printf("seqno %d    pieceNumber %d    src %d    des %d    current_hop %d. This hop has been traveled\n",  p->seqno, p->pieceNumber, p->src, p->dest, nodeinfo.address);
	      printf("\n");
	      /*free(&p->traveled_hops);
	      free(&p->msg);
	      free(p);
	      */
	      return 0;
	  }
	}
					
	/*  IS THIS PACKET IS FOR ME? */
	if (p->dest == nodeinfo.address) {
		switch (p->kind) {
		case NL_DATA:
			if (p->seqno == NL_packetexpected(p->src)) {
				length = p->length;
				memcpy(rb[p->src], (char *) p->msg, length);
				rb[p->src] = rb[p->src] + length;
				packet_length[p->src] += length;
			
				printf("This piece traveled %d hops\n", p->traveled_hops_count);

				if (p->pieceEnd) {
					CnetAddr tmpaddr;
					//length = p->pieceNumber * (linkinfo[arrived_on_link].mtu
					//		- PACKET_HEADER_SIZE) + p->length;
					length = packet_length[p->src];
					
					int p_checksum = p->checksum;
                                        int checksum = CNET_ccitt(
                                                        (unsigned char *) (receiveBuffer[p->src]),
                                                        (int) length);
                                        if (p_checksum != checksum) {
                                                /***************************send back error ack**************/
						//NL_savehopcount(p->src, p->hopcount, arrived_on_link);
                                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);

                                                tmpaddr = p->src; /* swap src and dest addresses */
                                                p->src = p->dest;
                                                p->dest = tmpaddr;

                                                p->kind = NL_ERR_ACK;
                                                //p->hopcount = 0;
						p->traveled_hops_count = 0;
						memset(p->traveled_hops, -1, MAXHOPS*sizeof(int));
						p->trans_time = 0;
                                                p->length = 0;
                                                flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0);
                                                return 0;
                                                /***************************end******************************/
                                        }
					
					if (CNET_write_application(receiveBuffer[p->src], &length) == -1) {
						//source node should send this msg again
						if (cnet_errno == ER_CORRUPTFRAME) {
							printf("Warning: host %d received a corrupt packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src);
						} else if (cnet_errno == ER_MISSINGMSG) {
							printf("Warning: host %d received a unordered packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src);
						}else if (cnet_errno == ER_BADSIZE){
							printf("Warning: host %d received a loss packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src);
						}
					} else {
					    printf("host %d received a correct packet (seqno = %d) from %d\n", nodeinfo.address, p->seqno, p->src);
					}
					  
					rb[p->src] = &receiveBuffer[p->src][0];
					packet_length[p->src] = 0;

					inc_NL_packetexpected(p->src);

					//NL_savehopcount(p->src, p->hopcount, arrived_on_link);
					NL_savehopcount(p->src, p->trans_time, arrived_on_link);
					
					//send a NL_ACK back to source host
					tmpaddr = p->src; /* swap src and dest addresses */
					p->src = p->dest;
					p->dest = tmpaddr;
					p->kind = NL_ACK;
					//p->hopcount = 0;
					p->traveled_hops_count = 0;
					memset(p->traveled_hops, -1, MAXHOPS*sizeof(int));
					p->trans_time = 0;
					p->length = 0;
					packet_length[p->src] = 0;
					//printf("right frame! up to app\n");
					flood3(packet, PACKET_HEADER_SIZE, arrived_on_link, 0);
					//printf("send ack\n");
				}
			}
			break;

		case NL_ACK:
			if (p->seqno == NL_ackexpected(p->src)) {
				//printf("ACK come!\n");
				inc_NL_ackexpected(p->src);
				//NL_savehopcount(p->src, p->hopcount, arrived_on_link);
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				CHECK(CNET_enable_application(p->src));
			}
			break;
		 case NL_ERR_ACK:
                        printf("ERROR ACK!\n");
                        if (p->seqno == NL_ackexpected(p->src)) {
                                //NL_savehopcount(p->src, p->hopcount, arrived_on_link);
                                NL_savehopcount(p->src, p->trans_time, arrived_on_link);
                                printf("packet %d (to %d) error!\n", p->seqno, p->src);
                                NL_PACKET * packettoresend = get_last_packet(p->src);
                                printf("length = %d seq = %d\n", packettoresend->length,
                                                packettoresend->seqno);

                                int a = packettoresend->checksum;
                                int b = CNET_ccitt((unsigned char *) (packettoresend->msg),
                                                (int) (packettoresend->length));
                                if (a == b) {
                                        printf("ok!\n");
                                } else
                                        printf("wrong!\n");
                                int len = PACKET_HEADER_SIZE + packettoresend->length;
                                flood3((char *) packettoresend, len, 0, 0);

                        }
                        break;
		default: ;
			//printf("it's nothing!====================\n");
		}
	}
	/* THIS PACKET IS FOR SOMEONE ELSE */
	else {
		// 		printf("hopcount = %d\n", p->hopcount);
		// 		printf("MAXHOPS = %d\n", MAXHOPS);
		//if (p->hopcount < MAXHOPS) { /* if not too many hops... */
			//printf("other's frame!\n");
			//printf("piece for another node arrives\n");	
			length = p->length;
			memcpy(rb[p->src], (char *) p->msg, length);
			rb[p->src] = rb[p->src] + length;
			packet_length[p->src] += length;

			if (p->pieceEnd) {
				//printf("last piece for another node arrives\n");
				//length = p->pieceNumber * (linkinfo[arrived_on_link].mtu
				//		- PACKET_HEADER_SIZE) + p->length;
				length = packet_length[p->src];
				//NL_savehopcount(p->src, p->hopcount, arrived_on_link);
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_PACKET wholePacket;

				wholePacket.src = p->src;
				wholePacket.dest = p->dest;
				wholePacket.kind = p->kind;
				wholePacket.seqno = p->seqno;
				//wholePacket.hopcount = p->hopcount;
				wholePacket.trans_time = p->trans_time;
				wholePacket.traveled_hops_count = p->traveled_hops_count;
				memcpy(wholePacket.traveled_hops,p->traveled_hops, MAXHOPS);
				wholePacket.pieceEnd = 0;
				wholePacket.pieceNumber = 0;
				wholePacket.length = length;
				packet_length[p->src] = 0;

				memcpy(wholePacket.msg, receiveBuffer[p->src], length);
				flood3((char *) &wholePacket, PACKET_SIZE(wholePacket), 0,
						arrived_on_link);
				rb[p->src] = &receiveBuffer[p->src][0];

			}

		//} else
		  //  printf("drop\n");
		/* silently drop */;
	}
	printf("\n");
	return (0);
}
Beispiel #7
0
/*  up_to_network() IS CALLED FROM THE DATA LINK LAYER (BELOW) TO ACCEPT
 A PACKET FOR THIS NODE, OR TO RE-ROUTE IT TO THE INTENDED DESTINATION.
 */
int up_to_network(char *packet, size_t length, int arrived_on_link) {
	//printf("up to network at hop %d\n", nodeinfo.address);
	NL_PACKET *p = (NL_PACKET *) packet;
	if (p->src == nodeinfo.address) {
		printf("drop a packet at %d, src = %d, des = %d, seqno = %d\n\n",
				nodeinfo.address, p->src, p->dest, p->seqno);
		return 0;
	}
	
	//printf("up to network at %d (from %d to %d)\n", nodeinfo.address, p->src, p->dest);
	++p->hopcount; /* took 1 hop to get here */
	mtu = linkinfo[arrived_on_link].mtu;
	p->trans_time += ((CnetTime) 8000 * 1000 * mtu
			/ linkinfo[arrived_on_link].bandwidth
			+ linkinfo[arrived_on_link].propagationdelay) * 100 / mtu;
	
	/*  IS THIS PACKET IS FOR ME? */
	if (p->dest == nodeinfo.address) {
		switch (p->kind) {
		case NL_DATA:
			if (p->seqno == NL_packetexpected(p->src)) {
				//length = p->length;
				//memcpy(rb[p->src], (char *) p->msg, length);
				//rb[p->src] = rb[p->src] + length;
				//packet_length[p->src] += length;
				RB_save_msg_link(p, arrived_on_link);
				
				if (p->pieceEnd) {
					RB_copy_whole_msg_link(p, arrived_on_link);
					up_to_application(p, arrived_on_link);
					return 0;
				}
			}
			break;

		case NL_ACK:
			if (p->seqno == NL_ackexpected(p->src)) {
				////("ACK come!\n");
				inc_NL_ackexpected(p->src);
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_set_has_resent(p->src, 0);
				CHECK(CNET_enable_application(p->src));
			}
			break;
		case NL_ERR_ACK:
			printf("NL_ERR_ACK!\n");
			if (p->seqno == NL_ackexpected(p->src)) {
				if (NL_get_has_resent(p->src) == 0) {
					NL_savehopcount(p->src, p->trans_time, arrived_on_link);
					NL_PACKET * packettoresend = get_last_packet(p->src);
					printf(
							"src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n",
							packettoresend->src, packettoresend->dest,
							packettoresend->seqno, packettoresend->length,
							packettoresend->checksum);
					printf("resend it\n");
					int len = PACKET_HEADER_SIZE + packettoresend->length;
					packettoresend->is_resent = 1;
					NL_set_has_resent(p->src, 1);
					//NL_inc_resent_times(p->src); // for debug
					flood((char *) packettoresend, len, 0, 0);

				} else {
					printf(
							"this packet has already been resent, dont resent it again\n");
				}
			} else {
				printf(
						"this packet has already been correct received, dont resent it again\n");
			}
			printf("\n");
			break;
			
		case NL_ERR_ACK_RESENT:
			printf("NL_ERR_ACK_RESENT!\n");
			if (p->seqno == NL_ackexpected(p->src)) {
				NL_savehopcount(p->src, p->trans_time, arrived_on_link);
				NL_PACKET * packettoresend = get_last_packet(p->src);
				printf(
						"resend a resent packet, src = %d, des = %d, seqno = %d, send_length = %d, checksum = %d\n",
						packettoresend->src, packettoresend->dest,
						packettoresend->seqno, packettoresend->length,
						packettoresend->checksum);
				//printf("this packet has been resent %d times before this time\n", NL_get_resent_times(p->src)); //for debug
				//NL_inc_resent_times(p->src); // for debug
				int len = PACKET_HEADER_SIZE + packettoresend->length;
				packettoresend->is_resent = 1;
				flood((char *) packettoresend, len, 0, 0);

			} else {
				printf(
						"this packet has already been correct received, dont resent it again\n");
			}
			printf("\n");
			break;
		default:
			//("it's nothing!====================\n");
			break;
		}
	}
	/* THIS PACKET IS FOR SOMEONE ELSE */
	else {
		if (p->hopcount < MAXHOPS) { /* if not too many hops... */
			//length = p->length;
			//memcpy(rb[p->src], (char *) p->msg, length);
			//rb[p->src] = rb[p->src] + length;
			if(p->kind != NL_DATA){
			  route_packet(p, arrived_on_link);
			} else{
			  RB_save_msg_link(p, arrived_on_link);
			  printf("finish new rb save msg\n");
			  if (p->pieceEnd){

				RB_copy_whole_msg_link(p, arrived_on_link);
				printf("finish copy whole msg\n");
				printf("p->length after copy = %d\n", p->length);
				route_packet(p, arrived_on_link);

			  }
			}
		} else {/* silently drop */;
		
		}
	}
	return 0;
}
Beispiel #8
0
/* This is a receive function for the gnutls handshake 
 * protocol. Makes sure that we have received all data.
 */
static int
parse_record_buffered_msgs (gnutls_session_t session,
                               gnutls_handshake_description_t htype,
                               handshake_buffer_st * hsk)
{
  gnutls_datum_t msg;
  mbuffer_st* bufel = NULL, *prev = NULL;
  int ret;
  size_t data_size;
  handshake_buffer_st* recv_buf = session->internals.handshake_recv_buffer;

  bufel = _mbuffer_head_get_first(&session->internals.record_buffer, &msg);
  if (bufel == NULL)
    return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;

  if (!IS_DTLS(session))
    {
      ssize_t remain, append, header_size;

      do
        {
          if (bufel->type != GNUTLS_HANDSHAKE)
            return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET);

          /* if we have a half received message the complete it.
           */
          remain =  recv_buf[0].length -
                recv_buf[0].data.length;

          /* this is the rest of a previous message */
          if (session->internals.handshake_recv_buffer_size > 0 && recv_buf[0].length > 0 && remain > 0)
            {
              if (msg.size <= remain)
                append = msg.size;
              else
                append = remain;
                  
              ret = _gnutls_buffer_append_data(&recv_buf[0].data, msg.data, append);
              if (ret < 0)
                return gnutls_assert_val(ret);

              _mbuffer_head_remove_bytes(&session->internals.record_buffer, append);
            }
          else /* received new message */
            {
              ret = parse_handshake_header(session, bufel, htype, &recv_buf[0]);
              if (ret < 0)
                return gnutls_assert_val(ret);

              header_size = ret;
              session->internals.handshake_recv_buffer_size = 1;

              _mbuffer_set_uhead_size(bufel, header_size);

              data_size = MIN(recv_buf[0].length, _mbuffer_get_udata_size(bufel));
              ret = _gnutls_buffer_append_data(&recv_buf[0].data, _mbuffer_get_udata_ptr(bufel), data_size);
              if (ret < 0)
                return gnutls_assert_val(ret);
              _mbuffer_set_uhead_size(bufel, 0);
              _mbuffer_head_remove_bytes(&session->internals.record_buffer, data_size+header_size);

              if (cmp_hsk_types(htype, recv_buf[0].htype) == 0)
                { /* an unexpected packet */
                  hsk->htype = recv_buf[0].htype;
                  return gnutls_assert_val(GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET);
                }

            }

          /* if packet is complete then return it
           */
          if (recv_buf[0].length ==
                recv_buf[0].data.length)
            {
              return get_last_packet(session, htype, hsk);
            }
          bufel = _mbuffer_head_get_first(&session->internals.record_buffer, &msg);
        } 
      while(bufel != NULL);
    
      /* if we are here it means that the received packets were not
       * enough to complete the handshake packet.
       */
      return gnutls_assert_val(GNUTLS_E_AGAIN);
    }
  else /* DTLS */
    {
      handshake_buffer_st tmp;

      do
        {
          /* we now 
           * 0. parse headers
           * 1. insert to handshake_recv_buffer
           * 2. sort handshake_recv_buffer on sequence numbers
           * 3. return first packet if completed or GNUTLS_E_AGAIN.
           */
          do
            {
              if (bufel->type != GNUTLS_HANDSHAKE)
                {
                  gnutls_assert();
                  goto next; /* ignore packet */
                }

              _gnutls_handshake_buffer_init(&tmp);

              ret = parse_handshake_header(session, bufel, htype, &tmp);
              if (ret < 0)
                {
                  gnutls_assert();
                  _gnutls_audit_log("Invalid handshake packet headers. Discarding.\n");
                  break;
                }

              _mbuffer_consume(&session->internals.record_buffer, bufel, ret);

              data_size = MIN(tmp.length, tmp.end_offset-tmp.start_offset+1);

              ret = _gnutls_buffer_append_data(&tmp.data, _mbuffer_get_udata_ptr(bufel), data_size);
              if (ret < 0)
                return gnutls_assert_val(ret);

              _mbuffer_consume(&session->internals.record_buffer, bufel, data_size);

              ret = merge_handshake_packet(session, &tmp);
              if (ret < 0)
                return gnutls_assert_val(ret);

            }
          while(_mbuffer_get_udata_size(bufel) > 0);

          prev = bufel;
          bufel = _mbuffer_dequeue(&session->internals.record_buffer, bufel);

          _mbuffer_xfree(&prev);
          continue;

next:
          bufel = _mbuffer_head_get_next(bufel, NULL);
        }
      while(bufel != NULL);

      /* sort in descending order */
      if (session->internals.handshake_recv_buffer_size > 1)
        qsort(recv_buf, session->internals.handshake_recv_buffer_size,
          sizeof(recv_buf[0]), handshake_compare);

      while(session->internals.handshake_recv_buffer_size > 0 &&
        recv_buf[LAST_ELEMENT].sequence < session->internals.dtls.hsk_read_seq)
        {
          _gnutls_audit_log("Discarded replayed handshake packet with sequence %d\n", recv_buf[LAST_ELEMENT].sequence);
          _gnutls_handshake_buffer_clear(&recv_buf[LAST_ELEMENT]);
          session->internals.handshake_recv_buffer_size--;
        }

        return get_last_packet(session, htype, hsk);
    }
}