/* ************************************************** */
int set_header(call_t *c, packet_t *packet, destination_t *dst) {
    struct nodedata *nodedata = get_node_private_data(c);
    struct neighbor *n_hop = get_nexthop(c, dst->id);
    destination_t destination;
    struct routing_header *header = (struct routing_header *) 
                                            (packet->data + nodedata->overhead);
    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};

    /* No route available */
    if (dst->id != BROADCAST_ADDR && n_hop == NULL) {
        return -1;
    } 

    /* Set routing header */
    header->dst = dst->id;
    header->src = c->node;
    header->hop = nodedata->hop;

    /* Set MAC header */
    if (dst->id == BROADCAST_ADDR) {
        destination.id = BROADCAST_ADDR;
    } else {
        destination.id = n_hop->id;        
    }
    destination.position.x = -1;
    destination.position.y = -1;
    destination.position.z = -1;

    return SET_HEADER(&c0, packet, &destination);
}
/* ************************************************** */
int set_header(call_t *c, packet_t *packet, destination_t *dst) {
    struct nodedata *nodedata = get_node_private_data(c);
    struct neighbor *n_hop = get_nexthop(c, &(dst->position));
    destination_t destination;
    struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead);
    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};

    /* if no route, return -1 */
    if (dst->id != BROADCAST_ADDR && n_hop == NULL) {
        nodedata->data_noroute++;
        return -1;
    }
    else if (dst->id == BROADCAST_ADDR) {
      n_hop->id = BROADCAST_ADDR;
    }

    /* set routing header */
    header->dst = dst->id;
    header->dst_pos.x = dst->position.x;
    header->dst_pos.y = dst->position.y;
    header->dst_pos.z = dst->position.z;
    header->src = c->node;
    header->src_pos.x = get_node_position(c->node)->x;
    header->src_pos.y = get_node_position(c->node)->y;
    header->src_pos.z = get_node_position(c->node)->z;
    header->type = DATA_PACKET;
    header->hop = nodedata->hop;

    /* Set mac header */
    destination.id = n_hop->id;
    destination.position.x = -1;
    destination.position.y = -1;
    destination.position.z = -1;
    return SET_HEADER(&c0, packet, &destination);
}
/* ************************************************** */
void forward(call_t *c, packet_t *packet) {  
    struct nodedata *nodedata = get_node_private_data(c);
    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};
    struct routing_header *header = (struct routing_header *) (packet->data + nodedata->overhead);
    struct neighbor *n_hop = get_nexthop(c, &(header->dst_pos));
    destination_t destination;    

    /* delivers packet to application layer */
    if (n_hop == NULL) {
        array_t *up = get_entity_bindings_up(c);
        int i = up->size;
        
        while (i--) {
            call_t c_up = {up->elts[i], c->node, c->entity};
            packet_t *packet_up;
            
            if (i > 0) {
                packet_up = packet_clone(packet);         
            } else {
                packet_up = packet;
            }
            
            RX(&c_up, packet_up);
        }

        return;
    }
    
    /* update hop count */
    header->hop--;
    if (header->hop == 0) {
        nodedata->data_hop++;
        packet_dealloc(packet);
        return;
    }
    

    /* set mac header */
    destination.id = n_hop->id;
    destination.position.x = -1;
    destination.position.y = -1;
    destination.position.z = -1;
    if (SET_HEADER(&c0, packet, &destination) == -1) {
        packet_dealloc(packet);
        return;
    }
    
    /* forwarding packet */
    nodedata->data_tx++;
    TX(&c0, packet);
}
/* ************************************************** */
void forward(call_t *c, packet_t *packet) {  
    struct nodedata *nodedata = get_node_private_data(c);
    call_t c0 = {get_entity_bindings_down(c)->elts[0], c->node, c->entity};
    struct routing_header *header = (struct routing_header *) 
        (packet->data + nodedata->overhead);
    struct neighbor *n_hop = get_nexthop(c, header->dst);
    destination_t destination;    

    /* No route available */    
    if (n_hop == NULL) {
        packet_dealloc(packet);        
        return;
    }
    
    /* Update hop count */
    header->hop--;

    /* Hop count reached */
    if (header->hop == 0) {
        packet_dealloc(packet);
        return;
    }

    /* Set MAC header */
    destination.id = n_hop->id;
    destination.position.x = -1;
    destination.position.y = -1;
    destination.position.z = -1;
    if (SET_HEADER(&c0, packet, &destination) == -1) {
        packet_dealloc(packet);
        return;
    }
    
    /* Forwarding packet */
    PRINT_ROUTING("forward: Node %d forwards a packet "
                  "(from %d to %d, hop limit %d)\n",
                   c->node, header->src, header->dst, 
                   header->hop);
    TX(&c0, packet);
}
示例#5
0
文件: v_api.c 项目: pqhwan/TCP
int v_connect(int socket, struct in_addr *addr, uint16_t port){

#ifdef DEBUG
	printf(" v_connect() Trying to connect\n");
#endif

	//bind the socket to a random port
	int ret;
	struct in_addr any_addr;
	any_addr.s_addr = 0;

	ret = v_bind(socket, &any_addr, rand()%MAXPORT);

	//something went wrong at v_bind (no socket, not valid pnum)
	if(ret < 0) {	
#ifdef DEBUG
	printf(" v_connect() error : v_bind() failed\n");
#endif
		
		return -1; 

	}

#ifdef DEBUG
	printf(" v_connect() : v_bind() success\n");
#endif

	socket_t *so = fd_lookup(socket);
	if (so == NULL) {

#ifdef DEBUG
		printf(" v_connect() error : fd_lookup() failed\n");
#endif
		set_socketstate(so, CLOSE);
		return -1;
	}

#ifdef DEBUG
	printf(" v_connect() : fd_lookup() success\n");
#endif
	
	//store it in the lookup table (urport, myport, uraddr) + init windows
	init_windows(so);	
	
	//populate socket with info	
	so->urport = port;
	so->uraddr = addr->s_addr;
	//my addr is the interface IP address we will be sending request out to
	interface_t *i = get_nexthop(so->uraddr);
	if (i == NULL) {
		set_socketstate(so, CLOSE);
		return -EHOSTUNREACH;
	}

	so->myaddr = i->sourcevip;
	so->myseq = rand() % MAXSEQ;
#ifdef SIMPLESEQ
	so->myseq = 0;
#endif

#ifdef DEBUG
	printf(" v_connect() : so->* success\n");
#endif

#ifdef DEBUG
			printf(" v_connect: Added socket %d to socket_table"_NORMAL_"\n", so->id);
#endif

	HASH_ADD(hh2, socket_table, urport, keylen, so);

	set_socketstate(so, SYN_SENT);

#ifdef DEBUG
	printf(" v_connect() : socket %d moved into state SYN_SENT\n", so->id);
#endif

	tcp_send_handshake(1, so);
	
#ifdef DEBUG
			printf(_RED_" v_connect: send syn"_NORMAL_"\n");
			printf(_BLUE_" v_connect: timed out"_NORMAL_"\n");
#endif

	time_t now = time(NULL);
	time_t next = now;
	time_t diff = 0;
	int count = 0;

	//send a connection request (first grip)
	while ((count < MAX_SYN_REQ)) {

		if (so->state == ESTABLISHED) {
			break;
		}
		
		next = time(NULL);
		diff = next-now;

		if (diff == 1) {
			tcp_send_handshake(1, so);
			count++;

#ifdef DEBUG
			printf(_RED_" v_connect: send syn"_NORMAL_"\n");
			printf(_BLUE_" v_connect: timed out"_NORMAL_"\n");
#endif

			now = next;
		}
	}

	// Could not connect
	if (so->state == SYN_SENT || so->state == CLOSE) {
		set_socketstate(so, CLOSED);
		return -ENOTCONN;
	}

	//commence buffer management
    int s = (int)socket;
    pthread_attr_t thr_attr;
    pthread_attr_init(&thr_attr);
    pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&so->th, &thr_attr, buf_mgmt, (void *) s);

	return 0;
}
示例#6
0
文件: v_api.c 项目: pqhwan/TCP
/**
* TODO : take the pseudo header function out. NOTE : make sure it is generic
* enough to be called by handshake funcs AND send data funcs.
* TODO : 3rd shake might have data
* TODO : RST
*/
void tcp_send_handshake(int gripnum, socket_t *socket){

	tcphdr *header = NULL;

	switch(gripnum) {

		case 0:
			printf("\t TODO : RST NOT IMPLEMENTED YET\n");

		case SYN_SENT://1'st shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, 0,0,1,0,0,0, WINSIZE); //half the max sequence number
			
			break;
		case SYN_RCVD://2'nd shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									(socket->myseq)++, socket->ackseq,
									0,1,0,0,1, WINSIZE);

			break;

		case ESTABLISHED://3'rd shake
			header = tcp_mastercrafter(socket->myport, socket->urport,
									++(socket->myseq), socket->ackseq, 
									0,0,0,0,1, WINSIZE);
			break;

		case FIN_WAIT_1:// from ESTABLISHED --> FIN_WAIT_1 state (FIN SEGMENT)
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		case CLOSE_WAIT: //regular ACK
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									0,0,0,0,1,MAXSEQ);
			break;

		case LAST_ACK: // moving from CLOSE_WAIT --> LAST_ACK (FIN SEGMENT)
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		case CLOSING: // moving from FIN_WAIT_1 --> CLOSING
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;
		case ACKNOWLEDGE:
			printf("RST, ACK\n");
			header = tcp_mastercrafter(socket->myport, socket->urport,
					socket->myseq, socket->ackseq,
					0,0,0,0,1,MAXSEQ);

		case RST: // RST packet
			header = tcp_mastercrafter(socket->myport, socket->urport,
									socket->myseq, socket->ackseq, 
									1,0,0,0,1,MAXSEQ);
			break;

		default:
			printf("\t WARNING : Unknown shake!\n");
			return;
	}

	//0. make sure TCP header is not NULL
	if (header == NULL) {
		printf("\tWARNING : Could not make TCP header\n");
		return;
	}

	struct pseudo_tcpp *tcp_packet = (uint16_t *)malloc(sizeof(struct pseudo_tcpp));
	memset(tcp_packet, 0x0, sizeof(struct pseudo_tcpp));

	//1. fill the pseudiheader part
	((uint32_t *)tcp_packet)[0] = socket->myaddr;
	((uint32_t *)tcp_packet)[1] = socket->uraddr;
	((uint8_t *)tcp_packet)[9] = (uint8_t)TCP;
	((uint16_t *)tcp_packet)[5] = ntohs((uint16_t)TCPHDRSIZE);


	//2. fill the header 
	tcp_hton(header);
	memcpy(&tcp_packet->tcp, header, TCPHDRSIZE);

	//3. data (NONE)
	//TODO : 3rd handshake could have data. 
	memset(tcp_packet->payload, 0, 1024);

	//4. checksum
	uint16_t checksum = tcp_checksum(tcp_packet, TCPHDRSIZE+12);
	

	//5. set the checksum in the TCP header
	header->check = checksum;
	if (header->check == 0) {
		printf("\t ERROR : something went wrong with checksum\n");
		header->check = 0xffffff;
	}

	//6. TODO : error checking
	interface_t *nexthop = get_nexthop(socket->uraddr);

	//TODO : packet top pass to ip
	char *packet = (char *)malloc(TCPHDRSIZE+IPHDRSIZE);

	if (packet == NULL) {
		printf("\t ERROR : Malloc failed\n");
		return;
	}

	//7. copy the TCP header to ip packet
	memset(packet, 0, TCPHDRSIZE+IPHDRSIZE);
	memcpy(packet, header, TCPHDRSIZE);

	//8. NO data, so you are done : pass to ip
	encapsulate_inip(socket->myaddr,socket->uraddr,(uint8_t)TCP,header, TCPHDRSIZE, &packet);

	//9. TCP/IP packet all set, sending time
	int ret = send_ip(nexthop, packet, TCPHDRSIZE+IPHDRSIZE);

	free(tcp_packet);
	free(packet);
	free(header);

	return;
}