void test_get_packet_type_peer_resp (void) { unsigned char test_value[24] = { '\0' }; test_value[1] = R_RESPONSE (PEER_OPCODE); packet_type answer = PEER_RESPONSE; packet_type result = get_packet_type (test_value); NP_ASSERT_EQUAL (answer, result); }
void test_get_packet_type_map_req (void) { unsigned char test_value[24] = { '\0' }; test_value[1] = R_REQUEST (MAP_OPCODE); packet_type answer = MAP_REQUEST; packet_type result = get_packet_type (test_value); NP_ASSERT_EQUAL (answer, result); }
static bool udp_helper_send(int *err, struct sa *dst, struct mbuf *mb, void *arg) { struct menc_media *st = arg; unsigned int length; zrtp_status_t s; const char *proto_name = "rtp"; enum pkt_type ptype = get_packet_type(mb); if (drop_packets(st)) return true; length = (unsigned int)mbuf_get_left(mb); /* only RTP/RTCP packets should be processed */ if (ptype == PKT_TYPE_RTCP) { proto_name = "rtcp"; s = zrtp_process_rtcp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else if (ptype == PKT_TYPE_RTP) { s = zrtp_process_rtp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else return false; if (s != zrtp_status_ok) { if (s == zrtp_status_drop) return true; warning("zrtp: send(port=%d): zrtp_process_%s failed" " (status = %d '%s')\n", sa_port(dst), proto_name, s, zrtp_log_status2str(s)); return false; } /* make sure target buffer is large enough */ if (length > mbuf_get_space(mb)) { warning("zrtp: zrtp_process_%s: length > space (%u > %u)\n", proto_name, length, mbuf_get_space(mb)); *err = ENOMEM; } mb->end = mb->pos + length; return false; }
static bool udp_helper_recv(struct sa *src, struct mbuf *mb, void *arg) { struct menc_media *st = arg; unsigned int length; zrtp_status_t s; const char *proto_name = "srtp"; enum pkt_type ptype = get_packet_type(mb); if (drop_packets(st)) return true; length = (unsigned int)mbuf_get_left(mb); if (ptype == PKT_TYPE_RTCP) { proto_name = "srtcp"; s = zrtp_process_srtcp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else if (ptype == PKT_TYPE_RTP || ptype == PKT_TYPE_ZRTP) { s = zrtp_process_srtp(st->zrtp_stream, (char *)mbuf_buf(mb), &length); } else return false; if (s != zrtp_status_ok) { if (s == zrtp_status_drop) return true; warning("zrtp: recv(port=%d): zrtp_process_%s: %d '%s'\n", sa_port(src), proto_name, s, zrtp_log_status2str(s)); return false; } mb->end = mb->pos + length; return false; }
int main(int argc, char **argv){ int sd, retval, count = 0; struct timeval tv; fd_set rfds; memset(&xmpp, 0, sizeof(xmpp)); sd = open_tcp_sd(); open_stream(sd, get_open_str(buf)); xmpp_login(sd, NULL, NULL); xmpp.status = FREE; xmpp.send_msg = send_msg; xmpp.recv_msg = recv_msg; while (1) { tv.tv_sec = 5; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(sd, &rfds); retval = select(sd+1, &rfds, NULL, NULL, &tv); if (retval < 0) continue; //just for test if (retval == 0 && !FD_ISSET(sd, &rfds)) { count += 5; if (xmpp.status != FREE) ; else if (count % 10 == 0 && count % 20 != 0) { xmpp.send_msg(sd, "201", "hello, new message"); } else if (count % 20 == 0) ;//xmpp.send_file("211", "main.c"); continue; } memset(xmpp.buf, 0, sizeof(xmpp.buf)); read(sd, xmpp.buf, sizeof(xmpp.buf)); switch (get_packet_type(xmpp.buf)) { case MSG_RECV: xmpp.recv_msg(xmpp.buf); break; case SI_DISCOVER: break; case SI_OFFERS: break; case IBB_INIT: break; case IBB_SEND: break; case IBB_CLOSE: break; default: fprintf(stderr, "<===\n%s", xmpp.buf); break; } } //send_msg(sd, "201", "message from 211"); while (1) { sleep(10); send_data(sd, "201", "text from 211", strlen("text from 211")); } close(sd); return 0; }
int ProtocolParser::process_in() { if (!is_complete()) { return Error_packet_not_complete; } switch (get_packet_type()) { case Packet_type_external_rsa_key : { c_Debug() << "process packet, type == 'Packet_type_external_rsa_key'" << "\r\n"; if (!got_rsa_key()) { // process external RSA public key if (parse_external_rsa_key_packet() == ProtocolParser::Error_no) { // send internal RSA public key std::vector<char> packet; int parse_result = prepare_rsa_internal_pub_key_packet(packet); if (parse_result == ProtocolParser::Error_no) { Net::send_data(own_node_->get_socket(), &packet[0], packet.size()); c_Debug() << "process packet, type == 'Packet_type_external_rsa_key', OK" << "\r\n"; return Error_no; } } c_Debug() << "process packet, type == 'Packet_type_external_rsa_key', Error_rsa_key_packet" << "\r\n"; return Error_rsa_key_packet; } break; } case Packet_type_login_data : { c_Debug() << "process packet, type == 'Packet_type_login_data'" << "\r\n"; if (!got_login_data_) { if (parse_login_packet() == ProtocolParser::Error_no) { // check login and passwd bool user_exist = db_.check_user_exist(login_, passwd_hash_); if (user_exist) { // get user ID by login int user_id; db_.get_user_id_by_login(&login_[0], &user_id); own_node_->set_user_id(user_id); // get node ID by name if (!node_name_.empty()) { int node_id = 0; if (db_.get_node_id_by_name(node_name_, &node_id)) { own_node_->set_node_id(node_id); } } // send login accept packet std::vector<char> accept_login_packet; prepare_packet(Packet_type_login_accept, TunnelCommon::Protocol::c_packet_login_accept, accept_login_packet); Net::send_data(own_node_->get_socket(), &accept_login_packet[0], accept_login_packet.size()); c_Debug() << "process packet, send login_accept_packet\r\n"; c_Debug() << "process packet, type == 'Packet_type_login_data', OK" << "\r\n"; return Error_no; } c_Debug() << "process packet, type == 'Packet_type_login_data', Error_parse_login_node_not_exist" << "\r\n"; return Error_parse_login_node_not_exist; } c_Debug() << "process packet, type == 'Packet_type_login_data', Error_parse_login_packet" << "\r\n"; return Error_parse_login_packet; } break; } default: { c_Debug() << "process packet, Error_unknown_packet" << "\r\n"; flush(); return Error_unknown_packet; } } flush(); return Error_no; }
/* * ******************************************* * Function: handle_transport_layer_packet * * Description: * * handle a transport layer * packet. Core transport layer handling * function , all the other funcitons * were written to support this big guy * * Parameters: * buffer - packet buffer * src_id - Source id * dest_id - Destination id * * ******************************************* */ void handle_transport_layer_packet( void * buffer , int src_id , int dest_id ) { int packet_type; int requested_mtu; int seq_no; int connect_id; void *realloc_buffer; int win_size ; void *packet_data; int cid_seq_no; int current_sender_id; int current_cid_state; int sender_id ; char *realloc_buf_ptr; int max_connections_permitted = get_state(&__max_connections); packet_type = get_packet_type(buffer); switch(packet_type) { case CONTROL_CONNECT: requested_mtu = get_requested_mtu(buffer); connect_id =allocate_sender(max_connections_permitted); sender_id = get_sender_id(buffer); if ( connect_id < max_connections_permitted) { init_state(&__session_tab.cid_info[connect_id].curr_state); set_state(&__session_tab.cid_info[connect_id].curr_state ,STATE_CONNECTED); __session_tab.cid_info[connect_id].sequence_number = 0; __session_tab.cid_info[connect_id].buf_len = 0; send_connect_ack(src_id , requested_mtu , connect_id,sender_id); } else { fprintf(stderr ,"%s", "\n Connection not possilbe all slots full \n"); } break; case CONTROL_ACK: seq_no = get_sequence_number(buffer); current_sender_id = get_sender_id(buffer); connect_id = get_cid(buffer); sender_buffer[current_sender_id].seq_no = seq_no; sender_buffer[current_sender_id].response_code = CONTROL_ACK; sender_buffer[current_sender_id].connection_id = connect_id; break; case CONTROL_DATA: { fprintf(stderr,"DATA packet received ... "); connect_id = get_cid(buffer); seq_no = get_sequence_number(buffer); sender_id = get_sender_id(buffer); cid_seq_no = __session_tab.cid_info[connect_id].sequence_number; current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); fprintf(stderr,"\n seq no = %d cid seq no = %d window size = %d CID = %d" , seq_no , cid_seq_no , get_window_size(buffer) , connect_id); /* are we getting the next sequnce number & we are connected */ if( ( seq_no == cid_seq_no + 1 ) ) { win_size = get_window_size(buffer); realloc_buffer = malloc(win_size + __session_tab.cid_info[connect_id].buf_len); if ( __session_tab.cid_info[connect_id].buf_len > 0 && ( current_cid_state != STATE_CLOSE)) { memcpy(realloc_buffer,__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len); realloc_buf_ptr = (char *) realloc_buffer + __session_tab.cid_info[connect_id].buf_len ; packet_data = (char *) buffer + TRASPORT_LAYER_SIZE ; memcpy(realloc_buf_ptr,packet_data , win_size); __session_tab.cid_info[connect_id].buf_len += win_size; free( __session_tab.cid_info[connect_id].data_buf); __session_tab.cid_info[connect_id].data_buf = realloc_buffer; __session_tab.cid_info[connect_id].sequence_number++; send_ack_request(src_id,seq_no,sender_id) ; } else { packet_data = (char *) buffer + TRASPORT_LAYER_SIZE ; memcpy(realloc_buffer,packet_data , win_size); __session_tab.cid_info[connect_id].buf_len += win_size; __session_tab.cid_info[connect_id].data_buf = realloc_buffer; __session_tab.cid_info[connect_id].sequence_number++; send_ack_request(src_id,seq_no,sender_id) ; } } else if ( seq_no == cid_seq_no ) { send_ack_request(src_id,seq_no,sender_id) ; } else { fprintf(stderr , "%s" , "\n Packet out of sequence number / duplicate discarded \n "); } } break; case CONTROL_FIN: fprintf(stderr ,"\n fin received "); connect_id = get_cid(buffer); sender_id = get_sender_id(buffer); current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); if ( current_cid_state == STATE_CONNECTED ) { nfd_buffer_receved(__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len); free(__session_tab.cid_info[connect_id].data_buf); __session_tab.cid_info[connect_id].buf_len = 0 ; } else { set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_FIN); } send_ack_request(src_id,0,sender_id); break; case CONTROL_CLOSE: connect_id = get_cid(buffer); set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_CLOSE); deallocate_connection(connect_id); fprintf(stderr , "\nRecevied close packet "); break; case CONTROL_CONNECT_ACK: seq_no = get_sequence_number(buffer); current_sender_id = get_sender_id(buffer); connect_id = get_cid(buffer); sender_buffer[current_sender_id].response_code = CONTROL_CONNECT_ACK; sender_buffer[current_sender_id].mtu_possible = get_window_size(buffer); sender_buffer[current_sender_id].connection_id = connect_id; fprintf(stderr , "\n Recieved control connect ack sender id %d mtu_possible %d " ,current_sender_id, sender_buffer[current_sender_id].mtu_possible ); break; default: /* None of the known control types */ /* dropping packet */ fprintf(stderr,"\n Not one of the known packet types, Type = %d " , packet_type ); break; } }
void process_inbound_udp(int sock) { struct sockaddr_in from; socklen_t fromlen; char buf[MAX_PACKET_LENGTH]; fromlen = sizeof(from); int read_result = spiffy_recvfrom(sock, buf, MAX_PACKET_LENGTH, 0, (struct sockaddr *) &from, &fromlen); printf("read %d bytes\n", read_result); //printf("incoming message from %s:%d\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); /* we just assume we got one packet everytime * if there are multiple packets in the buffer (whichi is rare), we just ignore them, * and everything will just work fine. */ struct network_packet_s* network_packet = (struct network_packet_s*)buf; net_to_host_header(& network_packet->header); print_packet_header(&network_packet->header); if(validate_packet(& network_packet->header) < 0){ printf("packet is invalid, skip\n"); return; } int packet_type = get_packet_type(& network_packet->header); /* get the peer who send this packet*/ bt_peer_t* peer = search_bt_peer(&config, (struct sockaddr *)&from); switch(packet_type) { case TYPE_WHOHAS: { struct network_packet_s* ihave_packet = malloc_ihave_packet(network_packet); /* this node has no such chunk */ if(ihave_packet == NULL){ return; } else{ //print_ihave_packet(ihave_packet); send_packet(ihave_packet, global_socket, (struct sockaddr *) &from); free(ihave_packet); } break; } case TYPE_IHAVE: { if(current_job == NULL){ return; } /* receiving a new IHAVE packet */ /* check whether there is alreay a connection with this peer */ struct receiver_connection_s* existing_connection = search_receiver_connection(receiver_connection_head, peer); if(existing_connection != NULL){ /* there is alreay a connection */ add_ihave_to_receiver_connection(existing_connection, network_packet); } /* there is no such connection */ else{ /* check if the number of connection reached the maximum */ if(get_receiver_connection_number(receiver_connection_head) >= max_receiver_connection){ return; } /* add add the hash whose chunk is in a CHUNK_STATUS_NOT_FOUND status * to a new connection */ else{ struct receiver_connection_s* new_connection = malloc_receiver_connection(network_packet, peer); /* if every chunk has a provider, the new_connection is NULL */ if(new_connection != NULL){ add_receiver_connection(new_connection); /* start the new connection */ struct network_packet_s* get_packet = start_connection(new_connection); //print_get_packet(get_packet); free(get_packet); } } } //print_receiver_connection_list(receiver_connection_head); break; } case TYPE_GET: { //print_get_packet(network_packet); /* check whether there is alreay a connection with this peer */ if(search_provider_connection(provider_connection_head, peer) != NULL){ printf("Provider connection already exists with peer %d , ignore GET\n", peer->id); return; } /* do nothing is the number of connection reached the maximum*/ if(get_provider_connection_number(provider_connection_head) >= max_provider_connection){ printf("Provider connection reached maximum with peer %d \n", peer->id); return; } struct provider_connection_s* new_connection = malloc_provider_connection(network_packet, peer); if(new_connection != NULL){ printf("Add new provider connection with peer %d \n", peer->id); add_provider_connection(new_connection); //print_provider_connection(new_connection); } //print_provider_connection_list(provider_connection_head); break; } case TYPE_DATA: { print_data_packet(network_packet); printf("received data packet, seq: %d, ack: %d\n ", network_packet->header.seq_number, network_packet->header.ack_number); /* check whether there is a connection with this peer */ struct receiver_connection_s* receiver_connection = search_receiver_connection(receiver_connection_head, peer); /* connection does not exist, ignore the data packet */ if(receiver_connection == NULL){ return; } int existing_seq_num = receiver_connection->chunk_list_head->chunk->received_seq_num; printf("expected data packet, seq: %d \n", 1 + existing_seq_num); int packet_seq_num = network_packet->header.seq_number; /* sequence number is illegal */ if(packet_seq_num < 0){ return; } /* old packet arrived, do nothing */ else if(packet_seq_num < (existing_seq_num + 1)){ return; } /* latter packet arrived first, send duplicate ACK */ else if(packet_seq_num > (existing_seq_num + 1)){ struct network_packet_s* ack_packet = malloc_ack_packet(existing_seq_num); send_packet(ack_packet, global_socket, (struct sockaddr *) &from); free(ack_packet); return; } /* the packet expected */ else{ gettimeofday(&receiver_connection->last_data_time, NULL); receiver_connection->status = RECEIVER_STATUS_RECEIVED_DATA; struct network_packet_s* ack_packet = malloc_ack_packet(1 + existing_seq_num); send_packet(ack_packet, global_socket, (struct sockaddr *) &from); free(ack_packet); /* save_data_packet */ save_data_packet(network_packet, receiver_connection); /* save the downloading chunk of the connnection, if it finihsed */ save_chunk(receiver_connection); /* continue to download next chunk, if finished first one */ reset_receiver_connection(receiver_connection); } break; } case TYPE_ACK: { //print_ack_packet(network_packet); struct provider_connection_s* provider_connection = search_provider_connection(provider_connection_head, peer); if(provider_connection == NULL){ return; } provider_control_by_ack(provider_connection, network_packet->header.ack_number); /* check if the data has been all send to a receiver */ if(provider_connection->last_packet_acked == CHUNK_DATA_NUM){ /* download finished */ finish_provider_connection(provider_connection); } break; } case TYPE_DENIED: { break; } default:{ break; } } }