Example #1
0
// This is a thread  started by srt_client_init(). It handles all the incoming 
// segments from the server. The design of seghanlder is an infinite loop that calls snp_recvseg(). If
// snp_recvseg() fails then the overlay connection is closed and the thread is terminated. Depending
// on the state of the connection when a segment is received  (based on the incoming segment) various
// actions are taken. See the client FSM for more details.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void *seghandler(void* arg)
{
  printf("seghandler receive\n");
  seg_t msg ;
  bzero(&msg,sizeof(msg));
  client_tcb_t *client ;
  while(1){
  	if(snp_recvseg(mainTcpSockId,&msg) < 0){
  		printf("client recvseg return negative hence exiting\n");
  		printf("exiting thread and closing main tcp connection\n");
  		fflush(stdout);
		pthread_exit(NULL);
  	}
  	printf("seghandler message received \n");
  	client = get_client_from_port(msg.header.dest_port);
	  	if(client){
	  	switch(msg.header.type){
	  		case SYNACK :{
	  			printf("SYNACK RECIEVED client port = %d and server port = %d\n", client->svr_portNum, msg.header.src_port);
	  			handle_syn_ack(client);
	  		}
	  		break;
	  		case FINACK :{
	  			printf("FINACK RECIEVED client port = %d and server port = %d \n", client->svr_portNum, msg.header.src_port);
	  			handle_fin_ack(client);
	  		}
	  		break;
	  		case DATAACK: {
	  			printf("DATAACK RECIEVED client port = %d and server port = %d \n", client->svr_portNum, msg.header.src_port);
	  			handle_data_ack(client,&msg);
	  		}
	  		break;
	  	}
    }else{
  		printf("client TCB not found for %d \n",msg.header.src_port);
  	}
  }
  fflush(stdout);
  return 0;
}
Example #2
0
// This is a thread  started by srt_server_init(). It handles all the incoming 
// segments from the client. The design of seghanlder is an infinite loop that calls snp_recvseg(). If
// snp_recvseg() fails then the overlay connection is closed and the thread is terminated. Depending
// on the state of the connection when a segment is received  (based on the incoming segment) various
// actions are taken. See the client FSM for more details.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void* seghandler(void* arg)
{
  seg_t* seg = (seg_t*) malloc(sizeof(seg_t));
  seg_t* ack = (seg_t*) malloc(sizeof(seg_t));
  // memset(&seg, 0, sizeof(seg));
  svr_tcb_t* tp = (svr_tcb_t*) malloc(sizeof(svr_tcb_t));

  while (1) {
    // Find the right server
    tp = NULL;
    if (snp_recvseg(tcp_socknum,seg) != 1) {
        printf("Can't receive data in server, ready to close\n");
      	close(tcp_socknum);
        pthread_exit(NULL);
    }

    // Get socketfd by port
    int sockfd = -1;
    for (int i = 0; i < MAX_TRANSPORT_CONNECTIONS; ++i)
      {
        if (svr_tcb_table[i] != NULL && svr_tcb_table[i] -> svr_portNum == seg->header.dest_port) {
          // Get the right tcb based on dest port
            sockfd = i; /*get socket number in srt for client port*/
            // tp -> client_port = seg.header.src_port;
            tp = svr_tcb_table[i];
          }
        }

      printf("Server sockfd =%d,Received seg header type =%d\n",sockfd,seg->header.type);

      if (!tp){
      printf("Server: Can't get server_tcp for the seg\n");
      continue;
        }

      printf("seghandler sockfd=%d , state=%d \n", sockfd, tp->state);
    switch(tp->state) {
      case CLOSED:
          printf("Server: sockfd=%d received seg in CLOSED\n", sockfd);
        break;
      case LISTENING: {
        if(seg->header.type == SYN) {
          pthread_mutex_lock(tp -> bufMutex);
          tp->client_portNum = seg->header.src_port;
          tp->state=CONNECTED;
          printf("Server:sockfd = %d Got SYN from client\n", sockfd);
          
          // Set tcb expect_seqNum
          tp -> expect_seqNum = seg->header.seq_num;
          pthread_mutex_unlock(tp -> bufMutex);

          // memset(&ack,0, sizeof(ack));
          // Received SYN and send SYNACK back
          ack->header.type = SYNACK;
          ack->header.src_port = tp -> svr_portNum;
          ack->header.dest_port = tp -> client_portNum;
          ack->header.length = 0;
          snp_sendseg(tcp_socknum, ack);
          printf("Server:sockfd = %d Sent SYNACK to client\n", sockfd);
        }
        else
          printf("Server: Listening received SYN\n");
        break;
   	 }
      case CONNECTED: 
      {
        switch (seg->header.type) {
          printf("Server: tp %d: receive %d\n", sockfd, seg->header.type);
          case SYN:
          {
            // Received SYN and send SYNACK back
            // seg_t ack;
            // memset(&ack,0, sizeof(ack));
            pthread_mutex_lock(tp -> bufMutex);
          	tp -> expect_seqNum = seg->header.seq_num;
            pthread_mutex_unlock(tp -> bufMutex);

            ack->header.type = SYNACK;
            ack->header.src_port = tp -> svr_portNum;
            ack->header.dest_port = tp -> client_portNum;
            ack->header.length = 0;
            snp_sendseg(tcp_socknum, ack);
            break;            
          }
          case DATA: {
          	// tp -> expect_seqNum will be updated if right; Otherwise, same old expect_seqNum
          	if (seg -> header.seq_num == tp -> expect_seqNum){
          		// Update tp -> expect_seqNum and store data in tp -> recvBuf 
          		restore_data(tp, seg);
          	}
          		// Send ack back anayway
          		ack->header.type = DATAACK;
            	ack->header.src_port = tp -> svr_portNum;
            	ack->header.dest_port = tp -> client_portNum;
            	ack->header.length = 0;
            	ack->header.ack_num = tp -> expect_seqNum;  // Send the new expect_seqNum(added by data length) if the expect_seqNum is right 
            	snp_sendseg(tcp_socknum, ack);
         
          	break;
          }
          case FIN:
          {
            time_t timer = time(NULL);
            printf("Server: tp %d: receive FIN %s", sockfd, ctime(&timer));

            // send FINACK
            // seg_t ack;
            // memset(&ack,0, sizeof(ack));
            ack->header.type = FINACK;
            ack->header.src_port = tp -> svr_portNum;
            ack->header.dest_port = tp -> client_portNum;
            ack->header.length = 0;
            snp_sendseg(tcp_socknum, ack);

            tp->state = CLOSEWAIT;

            // start a thread for CLOSE_WAIT_TIMEOUT; If time expires, Set tp state as CLOSED  
            pthread_t closetimer;
            pthread_create(&closetimer,NULL,closewait, (void*)tp);
            break;                    
          }
          default:
            break;
          }
        break;
      }
      case CLOSEWAIT:
        // receive FIN
        if (seg->header.type == FIN) {

          // send FINACK
          // seg_t ack;
          // memset(&ack,0, sizeof(ack));
          ack->header.type = FINACK;
          ack->header.src_port = tp -> svr_portNum;
          ack->header.dest_port = tp -> client_portNum;
          ack->header.length = 0;
          snp_sendseg(tcp_socknum, ack);
          printf("Server: sent FINACK in closewait\n");
          }
        else {
          printf("Server: Received not fin in CLOSEWAIT\n");
        }
        break;
      default:
        printf("Server: sockfd= %d: wrong state\n", sockfd);
        break;
    }
  }
}
Example #3
0
// This is a thread  started by srt_server_init(). It handles all the incoming 
// segments from the client. The design of seghandler is an infinite loop that calls snp_recvseg(). If
// snp_recvseg() fails then the overlay connection is closed and the thread is terminated. Depending
// on the state of the connection when a segment is received  (based on the incoming segment) various
// actions are taken. See the client FSM for more details.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void* seghandler(void* arg)
{

	/* seg_t struct to receive messages from client */

	seg_t* segPtr = calloc (1, sizeof(seg_t));

	if (NULL == segPtr) {

		free(segPtr);
		fprintf(stderr, "Failed to allocate memory for segment\n");
		exit(1);
	} 

	/* Infinite loop that receives segments */

	int src_nodeID;

	while (1) {
	
		/* For timing from CLOSEWAIT to CLOSED for server-client connection, loop through all connections */

		/* If Timer has already been started, then check for timeout */

		// int j;

		// for (j = 0; j < MAX_TRANSPORT_CONNECTIONS; j++) {

		// 	svr_tcb_t* sTp = svrConnList[j];

		// 	if ((NULL != sTp) && (sTp->timeSetBool) && (CLOSED != sTp->state)) { /* Don't want to track time if client connection already closed */

		// 		gettimeofday(&(sTp->t2), NULL); // keep checking the time

		// 		/* compute the elapsed time in milliseconds */
		// 	    sTp->elapsedTime = (sTp->t2.tv_sec - sTp->t1.tv_sec) * 1000.0;      // sec to ms
		// 	    sTp->elapsedTime += (sTp->t2.tv_usec - sTp->t1.tv_usec) / 1000.0;   // us to ms


		// 		//fprintf(stdout, "\nElapsed time: %lf\n", sTp->elapsedTime);
			
				
		// 		/* CLOSE after CLOSEWAIT period */
		// 		if (sTp->elapsedTime > (CLOSEWAIT_TIMEOUT * 1000.0)) {

		// 			fprintf(stdout, "\nNow closing server port %d after CLOSEWAIT_TIME: %f MS\n", sTp->svr_portNum, sTp->elapsedTime);

		// 			/* set state of that server port to CLOSED */

		// 			sTp->state = CLOSED;
		// 		}
		// 	}
		// }

		if (0 > snp_recvseg(svrSockGlobal, &src_nodeID, segPtr)) { /* Receive failed */
			;
		}

		/* Packet received */

		else {

			/* check the packet for bit errors */

			if (0 < checkchecksum(segPtr)) { // If the packet is valid

				/* Determine the serverPort it's meant for */

				int svrPort = segPtr->header.dest_port;
				int clientPort = segPtr->header.src_port;

				/* Determine what entry in the TCB table that serverPort corresponds to */

				int i;

				svr_tcb_t *tp;
				
				for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {

					if ((NULL != svrConnList[i]) && (svrPort == svrConnList[i]->svr_portNum)) {

						tp = svrConnList[i];
						tp->client_portNum = clientPort;
						break;
					}
				}

				if (NULL == tp) {
					fprintf(stderr, "Bad packet, found no matching port number on server side\n");
					exit(1);
				}

				/* Switch on the type of packet */

				switch(segPtr->header.type) {

					case SYN: /* Update server state and send a SYNACK */

						fprintf(stdout, "Server at server port: %d received SYN from client NodeID: %d at port: %d\n", svrPort, src_nodeID, clientPort);

						if ((LISTENING == tp->state) || (CONNECTED == tp->state)) {

							tp->state = CONNECTED;

							tp->client_nodeID = src_nodeID;

							/* Set tp->expect_seqNum using the sequence number in the received SYN segment */

							tp->expect_seqNum = segPtr->header.seq_num;

							/* Setup a SYNACK segment and send the segment to the server */

							seg_t* segSYNACK = calloc (1, sizeof(seg_t));

							if (NULL == segSYNACK) {

								free(segSYNACK);
								fprintf(stderr, "Failed to allocate memory for SYNACK segment\n");
								exit(1);
							} 

							segSYNACK->header.type = SYNACK;

							segSYNACK->header.src_port = svrPort;

							segSYNACK->header.dest_port = clientPort;

							/* Generate a checksum and add to PacketHeader */

							unsigned short int crcSumSYNACK = checksum(segSYNACK);

							segSYNACK->header.checksum = crcSumSYNACK;

							if (0 > snp_sendseg(svrSockGlobal, tp->client_nodeID, segSYNACK)) {
								fprintf(stderr, "Overlay send failed\n");
								exit(1);
							}

							free(segSYNACK);
						}

						break;

					case FIN: /* Stay at CLOSEWAIT and keep sending FINACKs */

						/* If currently CONNECTED or in CLOSEWAIT, stay/transition to CLOSEWAIT, and send FINACK */

						fprintf(stdout, "\nServer at server port: %d received FIN from client NodeID: %d at port: %d\n", svrPort, src_nodeID, clientPort);

						if ((CONNECTED == tp->state) || (CLOSEWAIT == tp->state)) {

							/* If originally CONNECTED, then start timer for this server-client port connection */

							if (CONNECTED == tp->state) {

/*								gettimeofday(&(tp->t1), NULL);
								tp->timeSetBool = 1; // indicate that timer has been started*/

								pthread_t segMain;

								int segRC = pthread_create(&segMain, NULL, serverTimer, tp); /* Params: fourth param is arg to function */

								if (segRC) {
								    fprintf(stderr, "pthread_create failed for server, rc=%d\n", segRC);
								    exit(segRC);
								}

								else {
									fprintf(stdout, "Starting timer for CLOSE_WAIT for server port: %d\n", svrPort);
								}
							}

							tp->state = CLOSEWAIT;

							/* Setup a FINACK segment and send the segment to the server */

							seg_t* segFINACK = calloc (1, sizeof(seg_t));

							if (NULL == segFINACK) {

								free(segFINACK);
								fprintf(stderr, "Failed to allocate memory for FINACK segment\n");
								exit(1);
							} 

							segFINACK->header.type = FINACK;

							segFINACK->header.src_port = svrPort;

							segFINACK->header.dest_port = clientPort;

							/* Generate a checksum and add to PacketHeader */

							unsigned short int crcSumFINACK = checksum(segFINACK);

							segFINACK->header.checksum = crcSumFINACK;

							if (0 > snp_sendseg(svrSockGlobal, tp->client_nodeID, segFINACK)) {
								fprintf(stderr, "Overlay send failed\n");
								exit(1);
							}

							free(segFINACK);
						}

						break;


					case DATA:

						fprintf(stdout, "Server at server port: %d received DATA from client NodeID: %d at port: %d\n", svrPort, src_nodeID, clientPort);

						if (CONNECTED == tp->state) {

							/* If the sequence number of the segment matches server tcb's expected sequence number */

							if (tp->expect_seqNum == segPtr->header.seq_num) {

								pthread_mutex_lock(tp->bufMutex);

								/* If receive buffer can still accommodate for received DATA segment */

								if ((tp->usedBufLen + segPtr->header.length) < RECEIVE_BUF_SIZE) {

									/* Store the received data into the receive buffer */

									char * receiveBuffer = tp->recvBuf;

									unsigned int usedBufferLen = tp->usedBufLen;

									memcpy(receiveBuffer + usedBufferLen, segPtr->data, segPtr->header.length);

									/* Increment usedBufLen and expect_seqNum by data size of received DATA segment */

									tp->expect_seqNum += segPtr->header.length;

									tp->usedBufLen += segPtr->header.length;

								}

								else { /* Simply discard received DATA segment */

									fprintf(stdout, "Receive buffer storage exceeded!!!\n");
								}

								pthread_mutex_unlock(tp->bufMutex);

							}

							/* Send DATAACK back to client w/ updated expect_seqNum or old expect_seqNum */
							
							seg_t* segDATAACK = calloc (1, sizeof(seg_t));

							if (NULL == segDATAACK) {

								free(segDATAACK);
								fprintf(stderr, "Failed to allocate memory for DATAACK segment\n");
								exit(1);
							} 

							segDATAACK->header.type = DATAACK;

							segDATAACK->header.src_port = svrPort;

							segDATAACK->header.dest_port = clientPort;

							segDATAACK->header.ack_num = tp->expect_seqNum;

							/* Generate a checksum and add to Packet Header */

							unsigned short int crcSumDATAACK = checksum(segDATAACK);

							segDATAACK->header.checksum = crcSumDATAACK;

							if (0 > snp_sendseg(svrSockGlobal, tp->client_nodeID, segDATAACK)) {
								fprintf(stderr, "Overlay send failed\n");
								exit(1);
							}

							free(segDATAACK);
						}

						else {

							fprintf(stdout, "BAD RECEIVING STATE, NOT CONNECTED\n");
						}

						break;
				}

				free(segPtr);

				/* Allocate memory for new segPtr to receive a segment from a client */

				segPtr = calloc (1, sizeof(seg_t));

				if (NULL == segPtr) {

					free(segPtr);
					fprintf(stderr, "Failed to allocate memory for segment\n");
					exit(1);
				}
			}

			else {

				/* Packet contains a bit error, so free it and drop the packet */

				fprintf(stdout, "Packet bit corruption detected!\n");

				free (segPtr);

				segPtr = calloc (1, sizeof(seg_t));

				if (NULL == segPtr) {
					free(segPtr);
					fprintf(stderr, "Failed to allocate memory for segment\n");
					exit(1);
				}
			}
		}
	}

  	return 0;
}
Example #4
0
// This is a thread  started by srt_server_init(). It handles all the incoming 
// segments from the client. The design of seghanlder is an infinite loop that calls snp_recvseg(). If
// snp_recvseg() fails then the overlay connection is closed and the thread is terminated. Depending
// on the state of the connection when a segment is received  (based on the incoming segment) various
// actions are taken. See the client FSM for more details.
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
void* seghandler(void* arg)
{
  	seg_t *segPtr = malloc(sizeof(seg_t));
	MALLOC_CHECK(segPtr);
	memset(segPtr, 0, sizeof(seg_t));

	char *segTypeStrings[] = {"SYN", "SYNACK", "FIN", "FINACK", "DATA", "DATAACK"};
	char *states[] = {"Unknown", "CLOSED", "LISTENING", "CONNECTED", "CLOSEWAIT"};
	int src_nodeID;

	while (snp_recvseg(overlay_conn_fd, &src_nodeID, segPtr) > 0) {

		if(!segPtr)
			break;

		//get the right server_tcb_t index
		unsigned int destPort = segPtr->header.dest_port;
		int idx = 0;
		while (idx < MAX_TRANSPORT_CONNECTIONS) {
			if (server_TCB_Table[idx] != NULL) {
				if (server_TCB_Table[idx]->svr_portNum == destPort){
					break;
				}
			}
			idx++;
		}

		if (idx < MAX_TRANSPORT_CONNECTIONS){
			svr_tcb_t *currentTCB = server_TCB_Table[idx];
			printf("\nReceived %s in state %s. client: %u, server: %u.\n", 
				segTypeStrings[segPtr->header.type], states[currentTCB->state], segPtr->header.src_port, segPtr->header.dest_port);

			switch(currentTCB->state) {
				case CLOSED:
				  //printf("State is CLOSED.\n");
				  printf("Doing nothing.\n");
				  break;

				case LISTENING:
				  //printf("State is LISTENING.\n");
				  if (segPtr->header.type == SYN){
				  	printf("Changing state to CONNECTED. client_portNum: %u, expect_seqNum: %u. Sending SYNACK.\n",
				  		 segPtr->header.src_port, segPtr->header.seq_num);
				  	currentTCB->state = CONNECTED;
				  	currentTCB->client_portNum = segPtr->header.src_port;
					currentTCB->expect_seqNum = segPtr->header.seq_num;
					currentTCB->client_nodeID = src_nodeID; //new
				  	
				  	//create SYNACK seg_t
					seg_t* synSegPtr = malloc(sizeof(seg_t));
					MALLOC_CHECK(synSegPtr);
					memset(synSegPtr, 0, sizeof(seg_t));
					synSegPtr->header.src_port = currentTCB->svr_portNum;
					synSegPtr->header.dest_port = currentTCB->client_portNum;
					synSegPtr->header.type = SYNACK;

					//send SYNACK seg_t
					if (snp_sendseg(overlay_conn_fd, currentTCB->client_nodeID, synSegPtr) < 0) {
						printf("Error sending SYNACK seg_t.\n");
					}
					free(synSegPtr);
				  } else {
				  	printf("Doing nothing.\n");
				  }
				  break;

				case CONNECTED:
				  //printf("State is CONNECTED.\n");
				  if (segPtr->header.type == SYN  && currentTCB->client_portNum == segPtr->header.src_port && currentTCB->client_nodeID == src_nodeID){
				  	printf("Sending SYNACK.\n");

				  	//create SYNACK seg_t
					seg_t* synSegPtr = malloc(sizeof(seg_t));
					MALLOC_CHECK(synSegPtr);
					memset(synSegPtr, 0, sizeof(seg_t));
					synSegPtr->header.src_port = currentTCB->svr_portNum;
					synSegPtr->header.dest_port = currentTCB->client_portNum;
					synSegPtr->header.type = SYNACK;

					//send SYNACK seg_t
					if (snp_sendseg(overlay_conn_fd, currentTCB->client_nodeID, synSegPtr) < 0) {
						printf("Error sending SYNACK seg_t.\n");
					}
					free(synSegPtr);
				  } else if (segPtr->header.type == FIN  && currentTCB->client_portNum == segPtr->header.src_port && currentTCB->client_nodeID == src_nodeID) {

				  	printf("Changing state to CLOSEWAIT and sending FINACK.\n");
				  	currentTCB->state = CLOSEWAIT;
				  	pthread_t closeWaitThread;
				    if (pthread_create(&closeWaitThread, NULL, closeWaitTimer, currentTCB)){
				    	printf("Error creating closeWaitTimer thread.\n");
				    }

				  	//create FINACK seg_t
					seg_t *finSegPtr = malloc(sizeof(seg_t));
					MALLOC_CHECK(finSegPtr);
					memset(finSegPtr, 0, sizeof(seg_t));
					finSegPtr->header.src_port = currentTCB->svr_portNum;
					finSegPtr->header.dest_port = currentTCB->client_portNum;
					finSegPtr->header.type = FINACK;

					//send FINACK seg_t
					if (snp_sendseg(overlay_conn_fd, currentTCB->client_nodeID, finSegPtr) < 0) {
						printf("Error sending FINACK seg_t.\n");
					}
					free(finSegPtr);

				  } else if (segPtr->header.type == DATA  && currentTCB->client_portNum == segPtr->header.src_port && currentTCB->client_nodeID == src_nodeID) {

					  	//create DATAACK seg_t
						seg_t *dataSegPtr = malloc(sizeof(seg_t));
						MALLOC_CHECK(dataSegPtr);
						memset(dataSegPtr, 0, sizeof(seg_t));
						dataSegPtr->header.src_port = currentTCB->svr_portNum;
						dataSegPtr->header.dest_port = currentTCB->client_portNum;
						dataSegPtr->header.type = DATAACK;

						//if the seq_nums match, add to buffer and increment relevant variables
						pthread_mutex_lock(currentTCB->bufMutex);
						if (segPtr->header.seq_num == currentTCB->expect_seqNum) {
							//put received data in recv buffer if it can fit
							if (segPtr->header.length + currentTCB->usedBufLen < RECEIVE_BUF_SIZE) {
								printf("Seq_nums match (%u)! Adding to buffer.\n", segPtr->header.seq_num);
								memcpy(currentTCB->recvBuf, segPtr->data, segPtr->header.length);
								currentTCB->recvBuf += segPtr->header.length;
								currentTCB->usedBufLen += segPtr->header.length;
								currentTCB->expect_seqNum += segPtr->header.length;
							} else {
								printf("Seq_nums match but recv Buf is too full. Dropping data and sending DATAACK.\n");
							}
						} else {
							printf("Out of order packet (%u).\n", segPtr->header.seq_num);
						}
						dataSegPtr->header.seq_num = currentTCB->expect_seqNum;
						pthread_mutex_unlock(currentTCB->bufMutex);

						//send DATAACK seg_t
						printf("Sending DATAACK with expect_seqNum %u.\n", dataSegPtr->header.seq_num);
						if (snp_sendseg(overlay_conn_fd, currentTCB->client_nodeID, dataSegPtr) < 0) {
							printf("Error sending DATAACK seg_t.\n");
						}
						free(dataSegPtr);
				  } else {
				  	printf("Doing nothing.\n");
				  }
				  break;

				case CLOSEWAIT:
				  //printf("State is CLOSEWAIT.\n");
				  if (segPtr->header.type == FIN  && currentTCB->client_portNum == segPtr->header.src_port && currentTCB->client_nodeID == src_nodeID){

				  	printf("Sending FINACK.\n");
				  	//create FINACK seg_t
					seg_t* synSegPtr = malloc(sizeof(seg_t));
					MALLOC_CHECK(synSegPtr);
					memset(synSegPtr, 0, sizeof(seg_t));
					synSegPtr->header.src_port = currentTCB->svr_portNum;
					synSegPtr->header.dest_port = currentTCB->client_portNum;
					synSegPtr->header.type = FINACK;

					//send FINACK seg_t
					if (snp_sendseg(overlay_conn_fd, currentTCB->client_nodeID, synSegPtr) < 0) {
						printf("Error sending FINACK seg_t.\n");
					}
					free(synSegPtr);

				  } else {
				  	printf("Doing nothing.\n");
				  }
				  break;

				default:
				  printf("Unknown state.\n");
				  break;
			}
		} else {
			printf("Couldn't find the server_tcb the client was trying to reach.\n");
		}

		memset(segPtr, 0, sizeof(seg_t));
	
	}

	printf("seghandler is closing the overlay connection.\n");
	close(overlay_conn_fd);
	free(segPtr);
	pthread_exit(NULL);
}
Example #5
0
void *seghandler(void* arg) {
	seg_t seg_recv;
	while (1 == snp_recvseg(connection, &seg_recv)) {
		int i;
		unsigned short int client_portNum	= seg_recv.header.dest_port;
		unsigned short int type				= seg_recv.header.type;
		client_tcb_t *tcb = NULL;
		for (i = 0; i < MAX_TRANSPORT_CONNECTIONS; i++) {
			pthread_mutex_lock(lock[i]);
			if (NULL != tcb_table[i] && client_portNum == tcb_table[i]->client_portNum) {
				tcb = tcb_table[i];
				break;
			}
			pthread_mutex_unlock(lock[i]);
		}
		if (NULL == tcb) {
			printf("%s There is no TCB matching port number %d.\n", output, client_portNum);
		}
		else {
			switch (tcb->state) {
				case CLOSED:
					break;
				case SYNSENT:
					if (SYNACK == type) {
						printf("%s TCB[%d] Received SYNACK!\n", output, i);
						printf("%s TCB[%d] State (SYNSENT) ==> (CONNECTED)\n", output, i);
						tcb->state = CONNECTED;
					}
					break;
				case CONNECTED:
					if (DATAACK == type) {
						printf("%s TCB[%d] Received DATAACK! Server Expect %d.\n", output, i, seg_recv.header.ack_num);
						pthread_mutex_lock(tcb->bufMutex);
						while (NULL != tcb->sendBufHead && tcb->sendBufHead->seg.header.seq_num < seg_recv.header.ack_num) {
							printf("%s TCB[%d] Free %d.\n", output, i, tcb->sendBufHead->seg.header.seq_num);
							segBuf_t *temp = tcb->sendBufHead;
							tcb->sendBufHead = tcb->sendBufHead->next;
							free(temp);
							tcb->unAck_segNum--;
						}
						if (NULL != tcb->sendBufHead) {
							sendN(i);
						}
						pthread_mutex_unlock(tcb->bufMutex);
					}
					break;
				case FINWAIT:
					if (FINACK == type) {
						printf("%s TCB[%d] Received FINACK!\n", output, i);
						printf("%s TCB[%d] State (FINWAIT) ==> (CLOSED)\n", output, i);
						tcb->state = CLOSED;
					}
					break;
				default:
					break;
			}
			pthread_mutex_unlock(lock[i]);
		}
	}
	return NULL;
}