Ejemplo n.º 1
0
static void timeoutFunction(Connection *conn) {
	SgmBuffElem *curr = NULL;

	DBGPRINT(RUSP_DEBUG, "RETRANSMISSION");

	if (pthread_rwlock_rdlock(&(conn->sndsgmbuff.rwlock)) > 0)
		ERREXIT("Cannot acquire read-lock.");

	curr = conn->sndsgmbuff.head;

	while (curr) {

		if (testSgmBuffElemAttributes(curr, RUSP_NACK, getTimeoutValue(&(conn->timeout)))) {

			updateSgmBuffElemAttributes(curr, 1, getTimeoutValue(&(conn->timeout)));

			sendSegment(conn, curr->segment);
		}

		curr = curr->next;
	}

	if (pthread_rwlock_unlock(&(conn->sndsgmbuff.rwlock)) > 0)
		ERREXIT("Cannot release read-write lock.");

	DBGPRINT(RUSP_DEBUG, "END OF RETRANSMISSION");
}
Ejemplo n.º 2
0
static void sendCACK(Connection *conn, const uint32_t ackn) {
	Segment acksgm;

	acksgm = createSegment(RUSP_CACK, 0, getWindowNext(&(conn->sndwnd)), ackn, NULL);

	sendSegment(conn, acksgm);
}
Ejemplo n.º 3
0
static void *senderLoop(void *arg) {
	Connection *conn = (Connection *) arg;
	char payload[RUSP_PLDS];
	size_t plds;

	pthread_cleanup_push(cleanupFunction, &(conn->sndusrbuff.mtx));

	while (1) {

		plds = waitLookMaxStrBuff(&(conn->sndusrbuff), payload, RUSP_PLDS);

		Segment sgm = createSegment((conn->sndusrbuff.size == plds) ? RUSP_PSH : RUSP_NUL, plds, getWindowNext(&(conn->sndwnd)), 0, payload);

		waitWindowSpace(&(conn->sndwnd), plds);

		addSgmBuff(&(conn->sndsgmbuff), sgm, RUSP_NACK);

		sendSegment(conn, sgm);

		slideWindowNext(&(conn->sndwnd), sgm.hdr.plds);

		DBGPRINT(RUSP_DEBUG, "SND (NXT): base:%u nxt:%u end:%u SNDUSRBUFF:%zu SNDSGMBUFF:%ld", getWindowBase(&(conn->sndwnd)), getWindowNext(&(conn->sndwnd)), getWindowEnd(&(conn->sndwnd)), getStrBuffSize(&(conn->sndusrbuff)), getSgmBuffSize(&(conn->sndsgmbuff)));

		popStrBuff(&(conn->sndusrbuff), plds);
	}

	pthread_cleanup_pop(1);

	return NULL;
}
Ejemplo n.º 4
0
void Transportlag::senderTransport(std::string enTekst)
{
	senderBuffer.clear();
	numberOfSequences = enTekst.size() / 80;

	if (enTekst.size() % 80 != 0)
	{
		numberOfSequences++;
	}
	senderBuffer = { "00000000" };							//Her laves probing headeren
	senderBuffer[0] += "001";
	senderBuffer[0] += intToString(numberOfSequences);

	for (size_t i = 1; i <= numberOfSequences; i++)			//Der laves headeren til hvert segment
	{														
		senderBuffer.push_back(intToString(i));
		if (i<numberOfSequences)
		{
			senderBuffer[i] += "000";
		}
		else
		{
			senderBuffer[i] += "100";
		}
		for (size_t k = 0; k < 80; k++)
		{															
			if (enTekst.size() == k + 80 * i - 80)						//Hvis et segment er mindre end 80 byte,
			{												//så der ikke mere at sende i det segment
				break;
			}
			senderBuffer[i] += enTekst[k+80*i-80];	
		}
	}

	//-----------------------------------------------

	for (size_t i = 0; i < senderBuffer.size(); i++)
	{
		std::cout << senderBuffer[i] << std::endl;
		sendSegment(senderBuffer[i]);
		//std::string somestuff = waitForACK();
	
	}
	
	//-----------------------------------------------
	
	

}
Ejemplo n.º 5
0
void activeClose(Connection *conn) {
	Segment fin;

	cancelThread(conn->sender);

	joinThread(conn->sender);

	fin = createSegment(RUSP_FIN, 0, getWindowNext(&(conn->sndwnd)), 0, NULL);

	addSgmBuff(&(conn->sndsgmbuff), fin, RUSP_NACK);

	setConnectionState(conn, RUSP_FINWT1);

	sendSegment(conn, fin);

	slideWindowNext(&(conn->sndwnd), 1);

	DBGPRINT(RUSP_DEBUG, "SND (NXT): base:%u nxt:%u end:%u SNDUSRBUFF:%zu SNDSGMBUFF:%ld", getWindowBase(&(conn->sndwnd)), getWindowNext(&(conn->sndwnd)), getWindowEnd(&(conn->sndwnd)), getStrBuffSize(&(conn->sndusrbuff)), getSgmBuffSize(&(conn->sndsgmbuff)));

	joinThread(conn->receiver);
}
Ejemplo n.º 6
0
/* Send all unsent segments from buffer to remote destination */
void sendFromSendBuffer (TCP_buffer* bufptr, int sock, struct sockaddr_in dest, struct sockaddr_in timer, int mode, TCP_buffer* ptr){
    /* Traverse the buffer and send valid segments that have not been 
     * sent before. A segment is valid if its seqno is within current 
     * send window. */
    TCP_buffer* p = bufptr;
    struct timeval tim;
    double t1;
    int time = 0;
    if (mode == SEND_ONE){
      p = ptr;
      if (isWithinWindow (sendWindow, p->ts.hdr.seq + p->len) && (p->txCount > 0)){
      
          /*if (fork() == 0){*/
          printf("Sending data...\n");
          /* Sending segment to destination */
          sendSegment (&(p->ts), p->len, sock, dest);

          /* Set timeout value using exponential backoff */
          /*time = (int)(RTO * pow(2.0, (double)p->txCount));
          */
          time = RTO;
          /* Sending request to timer process to add new entry */        
          sendTimerAddRequest (sock, timer, &(p->ts), time);     
          
          printf("Retransmitted segment seq = %d\n",p->ts.hdr.seq);        
          /* Updating number of tries and time of last transmission*/
          p->txCount = p->txCount + 1;
          gettimeofday(&tim, NULL);
          p->lastTxTime = tim.tv_sec + (tim.tv_usec/1000000.0);
          /*
          printf("lastTime = %.2f\n",p->lastTxTime);
          */
      }
      else {
        printf("RT segment not in window seq = %d txcount = %d\n",p->ts.hdr.seq, p->txCount);
        /*
        exit(1);
        */
      }
      
      return;
    }
    while (p != NULL){
      if (isWithinWindow (sendWindow, p->ts.hdr.seq + p->len) && (p->txCount == 0)){
        printf("Sending data...\n");
        /* Sending segment to destination */
        sendSegment (&(p->ts), p->len, sock, dest);
        /* Sending request to timer process to add new entry */
        
        sendTimerAddRequest (sock, timer, &(p->ts), time); 
        
        /*
         * printf("Sent segment seq = %d\n",p->ts.hdr.seq);
        */ 
        /* Updating number of tries */
        p->txCount = p->txCount + 1;
        gettimeofday(&tim, NULL);
        p->lastTxTime = tim.tv_sec + (tim.tv_usec/1000000.0);
        /*
        printf("lastTime = %.2f\n",p->lastTxTime);
        */
        
      }
      else {
        /*
        printf("segment not in window (%d,%d)seq = %d txcount = %d\n",sendWindow.low, sendWindow.high,p->ts.hdr.seq, p->txCount);
        */
      }
      p = p->next;
    }
}
Ejemplo n.º 7
0
int main (){

  int sock_main, sock_timer;
  struct sockaddr_in main, timer;
  char buf[TCP_SEGMENT_SIZE];
  char hostname[128];
  gethostname (hostname, sizeof(hostname));
  hp = gethostbyname(hostname); 
  
  sock_main = socket (AF_INET, SOCK_DGRAM, 0);
  
  if (sock_main < 0){
    perror("opening UDP socket for main use");
    exit(1);
  }

  bzero ((char*)&main, sizeof (main));
  main.sin_family = AF_INET;
  main.sin_port = TCPD_PORT;
  bcopy((void *)hp->h_addr_list[0], (void *)&main.sin_addr, hp->h_length);
    
  if (bind(sock_main, (struct sockaddr *)&main, sizeof(main)) < 0){
    perror("getting socket name of main TCPD port");
    exit(2);
  }

  printf("TCPD MAIN SOCKET : PORT = %d ADDR = %d\n",main.sin_port,main.sin_addr.s_addr);  
 
  bzero((char*)&timer, sizeof(timer));
  timer.sin_family = AF_INET;
  timer.sin_port = TIMER_PORT;
  bcopy((void *)hp->h_addr_list[0], (void *)&timer.sin_addr, hp->h_length);
  
  /* TODO : Initialize send and receive windows */
  sendWindow.low = 100;
  sendWindow.high = sendWindow.low + WINDOW_SIZE * TCP_MSS;
  recvWindow.low = 100;
  recvWindow.high = recvWindow.low + WINDOW_SIZE * TCP_MSS;

  while (1){
    
      int type = 0;
      void *ptr = NULL;
      int send_bytes = 0;
      int sock  = 0;
      int rlen = 0;
      int i = 0;
      TCP_segment ts;
      TCP_segment ts_recv;
      TCP_segment* tsp;
      struct sockaddr_in name;
      
      /*
      printf("Inside child process to receive data\n");
      */
      printf("\n\n");
      
      /* Initialize buffer to all zeroes */
      bzero(buf, TCP_MSS);
       
      /* Receive data from UDP port */
      rlen = recvSegment((TCP_segment *)&ts, sock_main, main);
       
      /* Get segment type (LOCAL, REMOTE or TIMER) */
      type = getSegmentType (ts);      

      /*
      printf("Segment Type = %d len = %d\n",type,rlen);
      */
    
      /* Segment received from local application process */
      if (type == LOCAL_SEGMENT) {
        
        printf("Received local segment len = %d\n",rlen);
        printf("sBufCount = %d\n",sBufCount);

        printf("Send window : (%d, %d)\n",sendWindow.low, sendWindow.high);        
        
        /* Receiving destination address when a CONNECT is called*/
        if (ts.hdr.seq == DEST_INFO) {
          memcpy ((void*)&dest, (void*)&(ts.data), sizeof(struct sockaddr_in));
          printf("Received destination info from app\n");
          continue;
        }
        /* Receiving source address when a BIND is called*/
        else if (ts.hdr.seq == SRC_INFO) {
          memcpy ((void*)&src, (void*)&(ts.data), sizeof(struct sockaddr_in));
          printf("Received source info from app port = %d\n",src.sin_port);
          continue;
        }

        /* 
        memcpy((void*)&buf[0], (void*)&ts.data, rlen-TCP_HEADER_SIZE);
        for (i = 0; i < rlen-TCP_HEADER_SIZE; ++i)
          printf("%d", buf[i]);
        printf("Recv bytes = %d\n",rlen-TCP_HEADER_SIZE);
        */
        if (sBufCount == BUFFER_SIZE) continue;
        /*
        sBufCount++;
        */
        /* Construct TCP segment with received data */
        ts = constructSegment((void*)&ts.data, rlen-TCP_HEADER_SIZE);
             
        /* Sequence number gets incremented by 
         * 1 for each byte sent */
        nextSeq = nextSeq + rlen-TCP_HEADER_SIZE;

        /* Add segment to send buffer */
        /* TODO: Revisit buffer overflow logic here */
        
        memcpy((void*)&buf, (void*) &ts.data, rlen);
        /*
        for (i = 0; i < rlen; ++i)
          printf("%c");
        printf("\n");
        */
        sBufPtr = addToBuffer (sBufPtr, &sBufCount, ts, rlen); 
          
        /* Send from send buffer */
        sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ALL, NULL); 
            
      }
      /* Segment received from remote process */
      
      else if (type == REMOTE_SEGMENT) {
        printf("Received remote segment len = %d\n",rlen);
        
        printf("Recv window : (%d, %d)\n",recvWindow.low, recvWindow.high);        
        
        /* TODO : Checksum here */ 
        /*
        printf("seq = %d crc = %d len = %d\n",ts.hdr.seq,ts.hdr.sum, rlen);
        
        memcpy((void*)&buf[0], (void*)&ts, rlen);
        for (i = 0; i < TCP_HEADER_SIZE; ++i)
          printf("%d",buf[i]);
        printf("\n");
        */

        /* Check if segment has valid checksum */
        if (!isValidChecksum(&ts, rlen)){
          printf("Checksum FAILURE\n");
          continue;
        }
        printf("Checksum SUCCESS\n");

 
        /* Check if ACK flag is set */
        if (isACK(&ts)){
          /* TODO :Handle ACK for already ACKed segments here */
          
            printf("Received ACK no = %d\n", ts.hdr.ack);
          
            /* Remove ACKed segment from buffer */
            sBufPtr = removeFromSendBuffer(sBufPtr, sock_main, timer, ts.hdr.ack);        
          
            /* Maintain ACK Count and compute RTO  */
            ackCount += 1;

            computeRTO ();

            continue;
        }
         
        /* Check if segment has valid checksum */
        /*
        if (!isValidChecksum(&ts, rlen)){
          printf("Checksum FAILURE");
          continue;
        }
        printf("Checksum SUCCESS\n");
        */
       
        /* Process received segment and return ptr to data*/
        ptr = processSegment((TCP_segment *)&ts, rlen);

        setACKFlag(&ts);

        /* TODO : How ACK set?*/
        ts.hdr.ack = ts.hdr.seq + rlen-TCP_HEADER_SIZE;
        if (isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE)|| (ts.hdr.seq < recvWindow.low)){
          
          int seq = ts.hdr.seq;            
          printf("Sending ACK for seq = %d\n",ts.hdr.seq);
          ts.hdr.seq = nextSeq;
          ts.hdr.urp = 0;
          ts.hdr.sum = 0;
          memcpy((void*)&buf, (void*)&ts, TCP_HEADER_SIZE);
  
          ts.hdr.sum = computeChecksum(&buf[0], TCP_HEADER_SIZE, &(ts.hdr.sum));
        
          /*
          printf("Checksum for ACK seq : %d crc : %d len : %d\n",ts.hdr.seq, ts.hdr.sum, TCP_HEADER_SIZE);
          
          for (i = 0; i < TCP_HEADER_SIZE; ++i)
            printf("%d",buf[i]);
          printf("\n");
          */
          /*ts.hdr.urp = REMOTE_SEGMENT;*/
          /*
          for (i = 0; i < TCP_HEADER_SIZE; ++i)
            printf("%d",buf[i]);
          printf("\n");
          */
          /* Sending ACK to remote process */
          sendSegment(&ts, TCP_HEADER_SIZE, sock_main, replyaddr);
          
          nextSeq = nextSeq + TCP_HEADER_SIZE;      
          ts.hdr.seq = seq;
        }
         /*printf("Sent ACK for seq = %d to dest = %d\n",ts.hdr.seq, replyaddr.sin_addr.s_addr);
          */
        if (!isWithinWindow(recvWindow, ts.hdr.seq+rlen-TCP_HEADER_SIZE) 
            || nextExpectedSeq > ts.hdr.seq){
            
          printf("Not within recv window seq = %d\n",ts.hdr.seq);
          continue;
        }
          
        printf("rBufCount = %d\n",rBufCount);          
        /*
        if (rBufPtr != NULL)  printf("RB : headseq = %d nes = %d\n",rBufPtr->ts.hdr.seq, nextExpectedSeq);
        if (rBufPtr != NULL && rBufPtr->ts.hdr.seq < nextExpectedSeq){
          printf("EXITING.......... \n");
          exit(1);
        }
        */
        /*
        if (nextExpectedSeq < recvWindow.low){
          printf("EXITING..\n");
          exit(1);
        }
        */
        
        if (rBufCount == BUFFER_SIZE) continue;
        
        /*rBufCount++;
        */
        /* TODO: Temporary hack to avoid recv buffer */
        /*sendData(&ts, rlen, sock_main, src);  
        
        continue;
        */

        /* Add segment to receive buffer */
        rBufPtr = addToBuffer (rBufPtr, &rBufCount, ts, rlen); 
          
        if (rBufPtr == NULL){
          printf("rbufptr = NULL post adding\n");
          continue; 
        }
        /* Update receive window */          
        updateWindow(&recvWindow, ts.hdr.seq, rlen-TCP_HEADER_SIZE); 
          
        /* Send data to local process */
        rBufPtr = sendFromRecvBuffer(rBufPtr, sock_main, src);
      }
      else if (type == TIMER_SEGMENT){

          TCP_buffer* ptr = NULL;

          printf("Received timer segment len = %d\n",rlen);
       
          memcpy((void*)&ptr, (void*)&(ts.data), sizeof(ptr));
          
          /* Update RTO on timeout. Message from timer 
           * implies timeout. */
          computeRTO();
          
          /* Retransmit segment to remote process */    
          sendFromSendBuffer (sBufPtr, sock_main, dest, timer, SEND_ONE, ptr);   
      }
  }  
  return 0;
}