/* 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); }
/* 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); }
/* 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; }
/* 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); }
/* 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; }
/* 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); }
/* 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; }
/* 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); } }