Example #1
0
int udp_fin_timeoutf(int ia, void* va)
{
    struct timeout_arg* targ = (struct timeout_arg*)va;
    fprintf(stderr,"Timeout for FIN with seqno %d\r\n",targ->seqno);

    //Deregister timeout function
    event_timeout_delete(udp_syn_timeoutf,va);

    int pnum = getpeernum(targ->sock_id,targ->to);

    //Create a packet for retransmission
    smalloc(struct entire_rudp_packet, erp);
    erp->rh.seqno = htonl(targ->seqno);
    erp->rh.type = htons(RUDP_FIN);
    erp->rh.version = htons(RUDP_VERSION);

    erp->rpb.data = NULL;
    erp->rpb.len = 0;

    //Actually send packet
    int nbytes = sizeof(struct rudp_hdr)+erp->rpb.len+16;
    size_t size = sizeof(struct sockaddr);

    if (sendto(targ->socket_desc,(void*)erp,nbytes,0,(struct sockaddr*)(targ->to),size)==-1)
    {
        perror("udp_fin_timeoutf: sendto");
        return -1;
    }

    //Register a new timeout for the packet
    smalloc(struct timeval,current_time);
    if (gettimeofday(current_time,NULL)<0)
    {
        perror("udp_fin_timeoutf: gettimeofday");
        return -1;
    }
    current_time->tv_usec += RUDP_TIMEOUT*2000;

    state[targ->sock_id].fin_timed_out[pnum] += 1;
    if (state[targ->sock_id].fin_timed_out[pnum]>RUDP_MAXRETRANS)
    {
        //Call the timeout function
        if (state[targ->sock_id].udp_event_fh((rudp_socket_t)targ->socket_desc,RUDP_EVENT_TIMEOUT,targ->to)==-1)
        {
            perror("udp_fin_timeoutf: event handler failed");
            return -1;
        }
        return 0;
    }
    //Actually register a new timeout function
    event_timeout(*current_time,udp_fin_timeoutf,(void*)state[targ->sock_id].ftap[pnum],"FIN packet timeout");
}
Example #2
0
int send_syn(int socket_desc, int sock_id, int pnum, struct sockaddr_in* to)
{
    //Create a new rudp header with SYN
    smalloc(struct rudp_hdr,rh);

    rh->version = htons(RUDP_VERSION);
    rh->type = htons(RUDP_SYN);

    int cnum = state[sock_id].curr[pnum]->seqno;
    int shift = state[sock_id].curr[pnum]->num;

    rh->seqno = ntohl(cnum - shift);
    state[sock_id].syn_seqno[pnum] = cnum - shift;;

    //Send a SYN
    int nbytes = sizeof(struct rudp_hdr);
    size_t size = sizeof(struct sockaddr_in);

    if (sendto(socket_desc,(void*)rh,nbytes,0,(struct sockaddr*)to,size)==-1)
        return -1;

    //Change state of (socket,peer) pair to SENT_SYN
    if (setsstate(sock_id,to,SENT_SYN)==-1)
        return -1;

    fprintf(stderr,"Sent SYN with seqno %d\r\n",ntohl(rh->seqno));

    //Register timeout for SYN
    smalloc(struct timeval,current_time);
    if (gettimeofday(current_time,NULL)<0)
    {
        perror("rudp_event_handler: gettimeofday");
        return -1;
    }
    current_time->tv_usec += RUDP_TIMEOUT*2000;

    //Create an argument for the event_timeout function
    state[sock_id].stap[pnum] = (struct timeout_arg*)malloc(sizeof(struct timeout_arg));
    state[sock_id].stap[pnum]->seqno = ntohl(rh->seqno);
    state[sock_id].stap[pnum]->sock_id = sock_id;
    state[sock_id].stap[pnum]->socket_desc = socket_desc;
    state[sock_id].syn_timed_out[pnum] = 0;

    state[sock_id].stap[pnum]->to = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
    memcpy(state[sock_id].stap[pnum]->to,to,sizeof(struct sockaddr_in*));
    state[sock_id].stap[pnum]->to->sin_addr = to->sin_addr;

    //Actually register the timeout handlet
    event_timeout(*current_time,udp_syn_timeoutf,(void*)(state[sock_id].stap[pnum]),"packet timeout");
    return 0;
}
Example #3
0
int send_data(int socket_desc, int sock_id, int pnum, struct sockaddr_in* to)
{
    //Find out how many packets we have to send
    int packets_to_send = state[sock_id].last_packet[pnum]-state[sock_id].curr[pnum]->num;
    if (packets_to_send>state[sock_id].window_size[pnum])
        packets_to_send = state[sock_id].window_size[pnum];

    int i;
    for (i=0; i<packets_to_send; i++)
    {
        //Move to next packet in queue
        state[sock_id].curr[pnum] = state[sock_id].curr[pnum]->next;
        //Create a full RUDP packet
        smalloc(struct entire_rudp_packet, erp);

        erp->rh.seqno = htonl(state[sock_id].curr[pnum]->seqno);
        erp->rh.type = htons(RUDP_DATA);
        erp->rh.version = htons(RUDP_VERSION);

        erp->rpb.len = state[sock_id].curr[pnum]->rp.len;        
        erp->rpb.data = (char*)malloc(erp->rpb.len);
        memcpy(erp->rpb.data,state[sock_id].curr[pnum]->rp.data,erp->rpb.len);

        //Actually send packet
        int nbytes = sizeof(struct rudp_hdr)+erp->rpb.len+16;
        size_t size = sizeof(struct sockaddr_in);

        if (sendto(socket_desc,(void*)erp,nbytes,0,(struct sockaddr*)to,size)==-1)
            return -1;

        fprintf(stderr,"Sent a DATA packet with seqno %d\r\n",ntohl(erp->rh.seqno));

        //Decrease window size by 1
        state[sock_id].window_size[pnum] -= 1;

        //Get the time at which the timeout handler for the packet should be called
        smalloc(struct timeval,current_time);
        if (gettimeofday(current_time,NULL)<0)
        {
            perror("rudp_event_handler: gettimeofday");
            return -1;
        }
        current_time->tv_usec += RUDP_TIMEOUT*2000;

        //Create an argument for the event_timeout function
        state[sock_id].curr[pnum]->tap = (struct timeout_arg*)malloc(sizeof(struct timeout_arg));   
        state[sock_id].curr[pnum]->tap->seqno = ntohl(erp->rh.seqno);
        state[sock_id].curr[pnum]->tap->sock_id = sock_id;
        state[sock_id].curr[pnum]->tap->socket_desc = socket_desc;
        state[sock_id].curr[pnum]->timed_out = 0;

        state[sock_id].curr[pnum]->tap->to = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in));
        memcpy(state[sock_id].curr[pnum]->tap->to,to,sizeof(struct sockaddr_in*));
        state[sock_id].curr[pnum]->tap->to->sin_addr = to->sin_addr;

        //Actually register the timeout handlet
        event_timeout(*current_time,udp_timeoutf,(void*)(state[sock_id].curr[pnum]->tap),"packet timeout");
    }

    //Send a FIN if no data was left
    if (packets_to_send<1) send_fin(socket_desc,sock_id,pnum,to);
    return 0;
}
Example #4
0
int udp_timeoutf(int ia, void* va)
{
    //Get the packet which was timed out
    struct timeout_arg* targ = (struct timeout_arg*)va;
    fprintf(stderr,"Timeout for packet with seqno %d\r\n",targ->seqno);

    //Deregister timeout function
    event_timeout_delete(udp_timeoutf,va);

    //Find which packet we have to retransmit
    int pnum = getpeernum(targ->sock_id,targ->to);
    int shift = (state[targ->sock_id].curr[pnum]->seqno)-(targ->seqno);

    int i;
    for (i=0;i<shift;i++)
    {
        //Move left {shift} times
        state[targ->sock_id].curr[pnum]=state[targ->sock_id].curr[pnum]->prev;
    }

    //Create a packet for retransmission
    smalloc(struct entire_rudp_packet, erp);
    erp->rh.seqno = htonl(targ->seqno);
    erp->rh.type = htons(RUDP_DATA);
    erp->rh.version = htons(RUDP_VERSION);

    erp->rpb.len = state[targ->sock_id].curr[pnum]->rp.len;
    erp->rpb.data = (char*)malloc(erp->rpb.len);
    memcpy(erp->rpb.data,state[targ->sock_id].curr[pnum]->rp.data,erp->rpb.len);

    //Actually send packet
    int nbytes = sizeof(struct rudp_hdr)+erp->rpb.len+16;
    size_t size = sizeof(struct sockaddr);

    if (sendto(targ->socket_desc,(void*)erp,nbytes,0,(struct sockaddr*)(targ->to),size)==-1)
    {
        //Return to the current packet
        for (i=0;i<shift;i++)
            state[targ->sock_id].curr[pnum]=state[targ->sock_id].curr[pnum]->next;
        perror("udp_timeoutf: sendto");
        return -1;
    }

    //Register a new timeout for the packet
    smalloc(struct timeval,current_time);
    if (gettimeofday(current_time,NULL)<0)
    {
        //Return to the current packet
        for (i=0;i<shift;i++)
            state[targ->sock_id].curr[pnum]=state[targ->sock_id].curr[pnum]->next;
        perror("udp_timeoutf: gettimeofday");
        return -1;
    }
    current_time->tv_usec += RUDP_TIMEOUT*2000;

    state[targ->sock_id].curr[pnum]->timed_out += 1;
    if (state[targ->sock_id].curr[pnum]->timed_out>RUDP_MAXRETRANS)
    {
        //Return to the current packet
        for (i=0;i<shift;i++)
            state[targ->sock_id].curr[pnum]=state[targ->sock_id].curr[pnum]->next;
        
        //Call the timeout function
        if (state[targ->sock_id].udp_event_fh((rudp_socket_t)targ->socket_desc,RUDP_EVENT_TIMEOUT,targ->to)==-1)
        {
            perror("udp_timeoutf: event handler failed");
            return -1;
        }
        return 0;
    }

    //Actually register a new timeout function
    event_timeout(*current_time,udp_timeoutf,(void*)state[targ->sock_id].curr[pnum]->tap,"packet timeout");

    //Return to the current packet
    for (i=0;i<shift;i++)
        state[targ->sock_id].curr[pnum]=state[targ->sock_id].curr[pnum]->next;

    return 0;
}
Example #5
0
int rudp_send_dgram(int pkt_type, rudp_session_t rsession)
{
    int i;
    struct timeval tv;
    int ret;
    gettimeofday(&tv, NULL);
    tv.tv_sec += (time_t)RUDP_TIMEOUT/1000;
    switch(pkt_type) {
    case RUDP_DATA:
        if(RUDP_SESSION_SYN != rsession->state) {
            printf("rudp_send_dgram(DATA): invalid session state\n");
            return -1;
        }
        rsession->wend = rsession->wstart;
        for(i = 0; i < RUDP_WINDOW; ++i) {
            if(NULL == rsession->wend) {
                break;
            }
            ret = sendto(rsession->rsock->sockfd,
                         (void*)rsession->wend,
                         sizeof(struct _rudp_dgram_t),0,
                         (struct sockaddr*)&(rsession->target),
                         sizeof(struct sockaddr) );
            if(ret < 0) {
                perror("sendto:");
                return -1;
            }
            rsession->wend->retrans++;
            rsession->wend = rsession->wend->next;
        }
        event_timeout(tv, rudp_ack_time_cb, rsession, "DATA TIMEOUT");
        break;
    case RUDP_SYN:
        if(RUDP_SESSION_OPENED != rsession->state) {
            printf("rudp_send_dgram(SYN): invalid session state\n");
            return -1;
        }
        if(rsession->head == NULL) {
            rsession->head = (rudp_dgram_t)malloc(sizeof
                                                  (struct _rudp_dgram_t));
            if(rsession->head == NULL) return -1;
            rsession->head->hdr.version = 1;
            rsession->head->hdr.type = RUDP_SYN;
            rsession->head->hdr.seqno = (u_int32_t)rand();
            rsession->head->data_len = 0;
            rsession->head->next = NULL;
        }
        ret = sendto(rsession->rsock->sockfd, (void*)rsession->head,
                     sizeof(struct _rudp_dgram_t), 0,
                     (struct sockaddr*)&(rsession->target),
                     sizeof(struct sockaddr) );
        if(ret < 0) {
            perror("sendto:");
            return -1;
        }
        rsession->head->retrans++;
        event_timeout(tv, rudp_ack_time_cb, rsession, "SYN TIMEOUT");
        break;
    case RUDP_FIN:
        if((RUDP_SESSION_DAT == rsession->state) &&
                (rsession->tail != NULL)) {
            ret = sendto(rsession->rsock->sockfd,
                         (void*)rsession->tail,
                         sizeof(struct _rudp_dgram_t), 0,
                         (struct sockaddr*)&(rsession->target),
                         sizeof(struct sockaddr) );
            if(ret < 0) {
                perror("sendto:");
                return -1;
            }
            rsession->tail->retrans++;
            event_timeout(tv, rudp_ack_time_cb,
                          rsession,"FIN TIMEOUT");
        }
        break;
    }
    return 0;
}
Example #6
0
/* Transmit a packet via UDP */
int send_packet(bool_t is_ack, rudp_socket_t rsocket, struct rudp_packet *p, struct sockaddr_in *recipient) {
  char type[5];
  short t=p->header.type;
  if(t == 1)
    strcpy(type, "DATA");
  else if(t == 2)
    strcpy(type, "ACK");
  else if(t == 4)
    strcpy(type, "SYN");
  else if(t == 5)
    strcpy(type, "FIN");
  else
    strcpy(type, "BAD");

  printf("Sending %s packet to %s:%d seq number=%u on socket=%d\n",type, 
       inet_ntoa(recipient->sin_addr), ntohs(recipient->sin_port), p->header.seqno, (int)rsocket);

  if (DROP != 0 && rand() % DROP == 1) {
      printf("Dropped\n");
  }
  else {
    if (sendto((int)rsocket, p, sizeof(struct rudp_packet), 0, (struct sockaddr*)recipient, sizeof(struct sockaddr_in)) < 0) {
      fprintf(stderr, "rudp_sendto: sendto failed\n");
      return -1;
    }
  }

  if(!is_ack) {
    /* Set a timeout event if the packet isn't an ACK */
    struct timeoutargs *timeargs = malloc(sizeof(struct timeoutargs));
    if(timeargs == NULL) {
      fprintf(stderr, "send_packet: Error allocating timeout args\n");
      return -1;
    }
    timeargs->packet = malloc(sizeof(struct rudp_packet));
    if(timeargs->packet == NULL) {
      fprintf(stderr, "send_packet: Error allocating timeout args packet\n");
      return -1;
    }
    timeargs->recipient = malloc(sizeof(struct sockaddr_in));
    if(timeargs->packet == NULL) {
      fprintf(stderr, "send_packet: Error allocating timeout args recipient\n");
      return -1;
    }
    timeargs->fd = rsocket;
    memcpy(timeargs->packet, p, sizeof(struct rudp_packet));
    memcpy(timeargs->recipient, recipient, sizeof(struct sockaddr_in));  
  
    struct timeval currentTime;
    gettimeofday(&currentTime, NULL);
    struct timeval delay;
    delay.tv_sec = RUDP_TIMEOUT/1000;
    delay.tv_usec= 0;
    struct timeval timeout_time;
    timeradd(&currentTime, &delay, &timeout_time);

    struct rudp_socket_list *curr_socket = socket_list_head;
    while(curr_socket != NULL) {
      if(curr_socket->rsock == timeargs->fd) {
        break;
      }
      curr_socket = curr_socket->next;
    }
    if(curr_socket->rsock == timeargs->fd) {
      bool_t session_found = false;
        /* Check if we already have a session for this peer */
        struct session *curr_session = curr_socket->sessions_list_head;
        while(curr_session != NULL) {
          if(compare_sockaddr(&curr_session->address, timeargs->recipient) == 1) {
            /* Found an existing session */
            session_found = true;
            break;
          }
          curr_session = curr_session->next;
        }
        if(session_found) {
          if(timeargs->packet->header.type == RUDP_SYN) {
            curr_session->sender->syn_timeout_arg = timeargs;
          }
          else if(timeargs->packet->header.type == RUDP_FIN) {
            curr_session->sender->fin_timeout_arg = timeargs;
          }
          else if(timeargs->packet->header.type == RUDP_DATA) {
            int i;
            int index;
            for(i = 0; i < RUDP_WINDOW; i++) {
              if(curr_session->sender->sliding_window[i] != NULL && 
                 curr_session->sender->sliding_window[i]->header.seqno == timeargs->packet->header.seqno) {
                index = i;
              }
            }
            curr_session->sender->data_timeout_arg[index] = timeargs;
          }
        }
      }
      event_timeout(timeout_time, timeout_callback, timeargs, "timeout_callback");
  }
  return 0;
}