Пример #1
0
void rel_timer ()
{
	//SPEEDTEST=========================
	struct timeval cur;
	gettimeofday(&cur, NULL);
	long int milliseconds_start = (prevsec * 1000) + (prevus / 1000);
	long int milliseconds_cur = (cur.tv_sec * 1000) + (cur.tv_usec / 1000);
	long diff = milliseconds_cur - milliseconds_start;
	if(diff >= 1000){
		if( rel_list && rel_list->c->sender_receiver == RECEIVER ){
			double thruput = numBitsReceivedBetweenTimers * 8 / (double)diff;
			fprintf(stderr, "thruput = %f kbps\n", thruput);
			prevsec = cur.tv_sec;
			prevus = cur.tv_usec;
			numBitsReceivedBetweenTimers = 0;
		}else{
			if(rel_list) printCWND(rel_list);
		}
	}
	//END===============================
	if (rel_list) {
		long int begin = (rel_list->rttTime.tv_sec * 1000) + (rel_list->rttTime.tv_usec / 1000);
		gettimeofday(&rel_list->helperTime, NULL);
		long int end = (rel_list->helperTime.tv_sec * 1000) + (rel_list->helperTime.tv_usec / 1000);
		long int diff = end - begin;

		if(diff > rel_list->rtt){
			retransmit(rel_list);
			gettimeofday(&rel_list->rttTime, NULL);
		}
	}
}
Пример #2
0
static void bluetooth_connection_handler(bool state) {
    if (state) {
        LOG(APP_LOG_LEVEL_DEBUG, "Bluetooth connected, starting transmit");
        retransmit(NULL);
    } else {
        LOG(APP_LOG_LEVEL_DEBUG, "Bluetooth disconnected");
    }
}
Пример #3
0
void next_event(struct params *p)
{
	struct timeval to, now;
	int el;
	int max;
	fd_set fds;
	int rtr = 3*1000;

	/* figure out select timeout */
	if (gettimeofday(&now, NULL) == -1)
		err(1, "gettimeofday()");

	/* check beacon timeout */
	el = elapsed(&p->blast, &now);
	if (el >= p->bint) {
		send_beacon(p);
		el = 0;
	}
	el = p->bint - el;
	to.tv_sec = el/1000/1000;
	to.tv_usec = el - to.tv_sec*1000*1000;

	/* check tx timeout */
	if (p->packet_try) {
		el = elapsed(&p->plast, &now);
		if (el >= rtr) {
			/* check if we gotta retransmit more */
			if (retransmit(p)) {
				el = 0;
			}
			else
				el = -1;
		}

		/* gotta retransmit in future */
		if (el != -1) {
			el = rtr - el;
			if ((to.tv_sec*1000*1000 + to.tv_usec) > el) {
				to.tv_sec = el/1000/1000;
				to.tv_usec = el - to.tv_sec*1000*1000;
			}
		}
	}

	/* select */
	FD_ZERO(&fds);
	FD_SET(p->rx, &fds);
	FD_SET(p->tap, &fds);
	max = p->rx > p->tap ? p->rx : p->tap;
	if (select(max+1, &fds, NULL, NULL, &to) == -1)
		err(1, "select()");

	if (FD_ISSET(p->tap, &fds))
		read_tap(p);
	if (FD_ISSET(p->rx, &fds))
		read_wifi(p);
}
Пример #4
0
void timeOutHandler(int signum){
  // TODO: Victor
  //FIXME: the signal handler function cannot have additional parameter put in, it can only deal with global variable. Might cause problem:
	int i;
	bool resetWindow = false;
	for(i = window->startIndex; i< window->startIndex + window->windowLength; i++){
		if (resetWindow == false ){
			window->timer[i]--;
			if (window->timer[i] == 0){
				printf("timeout happens at packet %d \n", i);
      				//window->resendCommand[count] = i;
				retransmit(i,sockfd, (struct sockaddr*)&cli_addr, clilen);
				resetWindow = true; 
   			 }
		}
	}

	alarm(1);
}
Пример #5
0
void t_stun_transaction::timeout(t_stun_timer t) {
	// RFC 3489 9.3
	if (num_transmissions < STUN_MAX_TRANSMISSIONS) {
		retransmit();
		start_timer_req_timeout();
		return;
	}
	
	// Report timeout to TU
	StunMessage *timeout_resp;
	timeout_resp = stunBuildError(*request, 408, "Request Timeout");
	log_file->write_report("STUN request timeout", "t_stun_transaction::timeout", 
			LOG_NORMAL);
	
	evq_trans_layer->push_stun_response(timeout_resp, tuid, id);
	MEMMAN_DELETE(timeout_resp);
	delete timeout_resp;
	
	state = TS_TERMINATED;
}
Пример #6
0
/**
 * Process an event from a local mailbox.
 *
 * \param[in,out] pi  Ping info
 *
 * \return 1 if processed an event 0 if not, negative error code otherwise
 */
static int
local_mbox_event(ping_info_t *pi)
{
  ExamsgMID mid;
  static Examsg ev;
  int ev_size;
  int s;

  ev_size = examsgRecv(local_mh, &mid, &ev, sizeof(ev));
  if (ev_size <= 0)
    return 0;

  switch (ev.any.type)
  {
    case EXAMSG_EXIT:
      {
         exa_nodeset_t dest_nodes;
         quit = true;
	 exa_nodeset_single(&dest_nodes, mid.netid.node);
         examsgAckReply(local_mh, &ev, EXA_SUCCESS, mid.id, &dest_nodes);
      }
      /* Return 0 because, despite we received a message, we do not want the
       * main loop to continue to process messages as it is asked to stop now.
       * So returning 0 juste means here "no need to read anymore messages" */
      return 0;

    case EXAMSG_SUP_PING:
      if (network_status() == 0)
	network_special_send(&mid, &ev, ev_size);
      break;

    case EXAMSG_ADDNODE:
      {
	exa_nodeset_t dest_nodes;
	examsg_node_info_msg_t *info = (examsg_node_info_msg_t *)&ev;

	s = network_add_node(info->node_id, info->node_name);

	exa_nodeset_single(&dest_nodes, mid.netid.node);
	examsgAckReply(local_mh, &ev, s, mid.id, &dest_nodes);
      }
      break;

    case EXAMSG_DELNODE:
      {
	exa_nodeset_t dest_nodes;

	s = network_del_node(((examsg_node_info_msg_t *)&ev)->node_id);

	exa_nodeset_single(&dest_nodes, mid.netid.node);
	examsgAckReply(local_mh, &ev, s, mid.id, &dest_nodes);
      }
      break;

    case EXAMSG_RETRANSMIT_REQ:
      if (network_status() == 0)
	{
	  ExamsgRetransmitReq *retreq = (ExamsgRetransmitReq *)&ev;

	  exalog_debug("will send a retransmit request for %d to %u",
		       retreq->count, retreq->node_id);

	  s = network_send_retransmit_req(retreq->node_id, retreq->count);
	  EXA_ASSERT(s == 0);
	  reset_ping(pi);
	}
      break;

    case EXAMSG_RETRANSMIT:
      if (network_status() == 0)
	{
	  ExamsgRetransmit *retr = (ExamsgRetransmit *)&ev;
	  exalog_debug("will retransmit messages: %d", retr->count);

	  retransmit(retr->count);
	  reset_ping(pi);
	}
      break;

    case EXAMSG_FENCE:
      {
	const examsgd_fencing_req_t *req =
	  &((examsgd_fencing_req_msg_t *)&ev)->request;

	network_handle_fence_request(req);
      }
      break;

    case EXAMSG_NEW_COMER:
      reset_ping(pi);
      break;

    default:
      {
       exa_nodeset_t dest_nodes;

       exa_nodeset_single(&dest_nodes, mid.netid.node);
       examsgAckReply(local_mh, &ev, EINVAL, mid.id, &dest_nodes);
       exalog_error("got unknown message (type %d)", ev.any.type);
       EXA_ASSERT(false);
      }
      break;
    }

  return 1;
}
Пример #7
0
char* Read(char* filename){
	FILE* fp = fopen(filename,"w");
	printf("goes in read function\n**************************************************************************************\n\n\n");
	int data_len = 0;
	int count = 0;
	u_int32_t previousSeq = 1;
	struct TCP_header * tcph = (struct TCP_header *) (datagram + sizeof(struct ip));
	int rcvlen = 0;	
	char* msg = NULL;
	u_int16_t datasize = 0;
	int contentlength = 50000;
	int first_http_pack = 1;
	char* http_buf = NULL;
	char buf[1024];
	struct TCP_header* ptcph = (struct TCP_header *)(buf + sizeof(struct iphdr));
	struct iphdr* iph = (struct iphdr*) buf;
	do{
	  printf("\n\n");
	  memset(buf,0,1024);
	  // Receive packet
   	  if((rcvlen = recv(sock2recv,buf,1024,0)) < 0){
		perror("recv failed");
		exit(0);
	  } 
          if(recv_flag_contains(FIN,buf))
	   {
	     printf("Packet signal SYN, gonna quit\n");
	     break;
	    }

 	  msg = buf + sizeof(struct iphdr) + 4 * ptcph->doff;
//	  printf("\n****************************************\n********************** msg is\n%s\n**********************************\n***************************************\n",msg);
	  printf("recvlen is %d\tseq num is: %d\n",rcvlen,(ntohl(ptcph->seq) - relative_first_seq));
	  if(rcvlen == 0){
		continue;
	  };
	  datasize = ntohs(iph->tot_len) - (sizeof(struct iphdr) + 4 * ptcph->doff);
 	  // if data size greater than zero
	  if(datasize > 0){
		printf("datasize is %d\n",datasize);
		if(previousSeq >= ntohl(ptcph->seq)|| not_correct_seq(buf,ackNum)){
			printf("Got duplicate packet previousSeq is\t%u now seq is \t%u\tdatasize is\t%d\n",(previousSeq - relative_first_seq),(ntohl(ptcph->seq) - relative_first_seq),datasize);
			retransmit(buf);
			continue;
		}
		msg = buf + sizeof(struct iphdr) + 4 * ptcph->doff;
		count = strlen(msg);
		// handle http header
		if(first_http_pack){
			data_len = datasize;
			char* slen = NULL;
//			printf("\nFirst time\n");
//			printf("msg is :\n%s\n",msg);
			first_http_pack = 0;
			if(!(contain_substr(msg,"HTTP/") && contain_substr(msg, "200") && contain_substr(msg,"OK")) )
			{
				printf("HTTP header code is not \"200 OK\", gonna quit!\n");
//				printf("Msg is\n%s\n",msg);
				exit(0);
			}
			slen = indexOfString(msg,"Content-Length");
			if(slen != NULL){
				slen = strchr(slen,':');
				slen++;
				contentlength = atoi(slen);
				printf("Content-Length is :\t %d\n",contentlength);
			} else {
				printf("\ndid not find Content-Length\n\n");
				exit(0);
			}
			printf("First time\n");
			http_buf = malloc(contentlength + 1000);
			memset(http_buf,0,contentlength + 1000);
		}
		strcat(http_buf,msg);
//		printf("BODY\n%s\n",msg);
		previousSeq = ntohl(ptcph->seq);
		printf("previousSeq is %d\n",(previousSeq - relative_first_seq));
	  } else {
		if(ntohl(ackNum) > contentlength){
			printf("got all data from packets: %u bytes, gonna quit\n",(ntohl(ackNum) - relative_first_seq));
			break;
		}
		printf("Received rubbish, go on\n");
		continue;
	  }
	  // Respond ACK
	  iph->tot_len = sizeof(struct iphdr) + sizeof(struct TCP_header) ;
	  tcph->seq = ptcph->ack_seq;
 	  tcph->ack_seq = htonl(ntohl(ptcph->seq) + datasize); 
	  tcph->psh = 0;
	  tcph->doff = 5;
	  tcph->ack = 1;
	  tcph->fin = 0;
 	  tcph->rst = 0;
	  /* Check sum */
	  tcph->check = 0;
	  tcph->check = tcp_csum(send_addr,tcph,0,srcaddr);
	  if(sendto(sock2send,datagram,iph->tot_len, 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) 
	  {
		perror("sendto failed");
	 } 
	 printf("Send succss\n");
 	ackNum = htonl((ntohl(ackNum) + datasize));	
      }while((!recv_flag_contains(FIN,buf)));
//	printf("receive size is %d\n",count);
//	printf("%s\n",http_buf);
	printf("Read done!\n");
	fwrite(http_buf,1,(contentlength + 1000),fp);
	return http_buf; 
}
Пример #8
0
 sendRequestedFile(char* serverIP,char* portNo, char* fName){
	int sockfd, newsockfd, portno,iofd;
	int maxfd,connfd,maxi=-1;
	int i,nready;
	struct sockaddr_in serv_addr,server_addr;
	int serv_len=sizeof(serv_addr);
	socklen_t server_len =sizeof(server_addr);
	int n;

	char filename[128];
	sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
	__android_log_write(ANDROID_LOG_INFO, "tftp-client", "sendRequestedFile entered");
	if (sockfd < 0)
	{
		__android_log_write(ANDROID_LOG_INFO, "tftp-client", "error opening socket");
        server_clean(serverdata);
    }

    strcpy(serverdata.filename,fName);
    sprintf(filename,"filename is %s",serverdata.filename);
    __android_log_write(ANDROID_LOG_INFO, "tftp-client",filename);
    
	memset((char *) &serv_addr,0, sizeof(serv_addr));
	memset((char *) &server_addr,0, sizeof(server_addr));
	portno = atoi(portNo);
	serv_addr.sin_family = AF_INET;
    inet_pton(AF_INET,serverIP,&serv_addr.sin_addr.s_addr);
    serv_addr.sin_port = htons(portno);
    maxfd=sockfd;
    FD_ZERO(&allset);
    FD_SET(sockfd, &allset);

	printf("++++++++++++++++++++++++++Client starts+++++++++++++++++++++++++++\n");

    serverdata.f=FileOpen(serverdata.filename);
    if(serverdata.f==NULL)
    {
        __android_log_write(ANDROID_LOG_INFO, "tftp-client", "File does not exist");
        //send_error(k);
        //clients[k].state=2;//state change to 2
        server_clean(serverdata);
        exit(1);
    }
    else
    {
    	char filesize[128];
		__android_log_write(ANDROID_LOG_INFO, "tftp-client", "File found");
        fseek (serverdata.f , 0 , SEEK_END);
        serverdata.filesize = ftell (serverdata.f);
        rewind (serverdata.f);
        
         sprintf(filesize,"filesize is %d",serverdata.filesize);
    	__android_log_write(ANDROID_LOG_INFO, "tftp-client",filesize);
        //printf("filesize=%d\n",serverdata.filesize);
        //clients[k].state=1;//state change to 1
    }
   	/*if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
    {
	      __android_log_write(ANDROID_LOG_INFO, "tftp-client", "Error connecting");
	      exit(1);
	}*/

	struct timeval select_timeout;
	select_timeout.tv_sec=4;
	select_timeout.tv_usec=0;
	serverdata.fd=sockfd;
	serverdata.addr = serv_addr;
	serverdata.block = 1;
	send_wrq();
	//rc4_state_clean(&rc4state);
	
	while(1){
		
		nready=select(maxfd+1,&allset,NULL,NULL,NULL);//select return 0 if timeout ,otherwise return # of ready fd

		if(nready==0){//timeout
		char blocknum[128];
        __android_log_write(ANDROID_LOG_INFO, "tftp-client", "Timeout happened");
		sprintf(blocknum,"Block num last sent is %d",serverdata.block);
    	__android_log_write(ANDROID_LOG_INFO, "tftp-client",blocknum);
		retransmit();

			select_timeout.tv_sec=4;
			select_timeout.tv_usec=0;
			continue;
		}
		//if(FD_ISSET(sockfd,&allset)){
			//new connection

				if(n=recvfrom(sockfd, buffer, BUFFERSIZE+4, 0,(struct sockaddr *)&server_addr,(socklen_t *)&server_len)<0)
				   __android_log_write(ANDROID_LOG_INFO, "tftp-client","receive error");
				else
				{
					rc4_init(&rc4state,rc4key,strlen(rc4key));
				   __android_log_write(ANDROID_LOG_INFO, "tftp-client","received some data");
				   serverdata.fd=sockfd;
                   serverdata.size=0;
                   serverdata.addr=server_addr;
                   serverdata.addr_len=server_len;
				  

				   memset(serverdata.buffer,0,BUFFERSIZE+4);
				   memset(serverdata.encryptedbuffer,0,BUFFERSIZE+4);
				  		
				  memcpy(serverdata.encryptedbuffer,buffer,sizeof(buffer));
				  rc4_crypt(&rc4state,serverdata.encryptedbuffer,serverdata.buffer,sizeof(serverdata.encryptedbuffer));
				  //memcpy(serverdata.buffer,buffer,BUFFERSIZE+4);
				  //rc4_crypt(serverdata.rc4state,serverdata.encryptedbuffer,serverdata.buffer,strlen(serverdata.encryptedbuffer));
		           state_machine();
				}
			if(serverdata.last_block == 1)
				break;
			}
			serverdata.last_block =0;
			printf("last block sent\n");
		
			/*for(i=0;i<MAX_CLIENT;++i){
				if(clients[i].fd<0){
					clients[i].fd=connfd;
					clients[i].size=0;
					clients[i].addr=cli_addr;
					clients[i].addr_len=cli_len;
					memcpy(clients[i].buffer,buffer,BUFFERSIZE);
					state_machine(i);
					clients[i].time=(int)time(NULL);
					break;
				}
			}
			if(i==MAX_CLIENT){
				printf("too many clients\n");
				continue;
			}
			FD_SET(connfd,&allset);
			if(connfd>maxfd){
				maxfd=connfd;
			}
			if(i>maxi) maxi=i;
			if(--nready<=0){
				continue;
			}*/
		//}
		//old connection
	/*for(i=0;i<=maxi;++i){
			if((iofd=clients[i].fd)<0) continue;
			if(FD_ISSET(iofd,&rset)){
				printf("\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~~OLD CONNECTION %d~~~~~~~~~~~~~~~~~~~~~~~\n",i);
				if(n=recvfrom(iofd, buffer, BUFFERSIZE, 0,  (struct sockaddr *)&cli_addr, (socklen_t *)&cli_len)<0) error("receive error");
				memcpy(clients[i].buffer,buffer,BUFFERSIZE);
				state_machine(i);
//				client_read(i);
				if(--nready<=0) break;/
				break;
			}
		}
			select_timeout.tv_sec=1;
			select_timeout.tv_usec=0;
		//otherwise, timeout*/

	//}
}
Пример #9
0
int trans_layer::update_uac_trans(trans_bucket* bucket, sip_trans* t, sip_msg* msg)
{
    assert(msg->type == SIP_REPLY);

    cstring to_tag;
    int     reply_code = msg->u.reply->code;

    DBG("reply code = %i\n",msg->u.reply->code);

    if(reply_code < 200){

	// Provisional reply
	switch(t->state){

	case TS_CALLING:
	    t->clear_timer(STIMER_A);
	    t->clear_timer(STIMER_B);
	    // fall through trap

	case TS_TRYING:
	    t->state = TS_PROCEEDING;
	    // fall through trap

	case TS_PROCEEDING:
	    goto pass_reply;

	case TS_COMPLETED:
	default:
	    goto end;
	}
    }
    
    to_tag = ((sip_from_to*)msg->to->p)->tag;
    if((t->msg->u.request->method != sip_request::CANCEL) && !to_tag.len){
	DBG("To-tag missing in final reply (see sipctrl.conf?)\n");
	if (!SipCtrlInterfaceFactory::accept_fr_without_totag)
	    return -1;
    }
    
    if(t->msg->u.request->method == sip_request::INVITE){
    
	if(reply_code >= 300){
	    
	    // Final error reply
	    switch(t->state){
		
	    case TS_CALLING:

		t->clear_timer(STIMER_A);

	    case TS_PROCEEDING:
		
		t->state = TS_COMPLETED;
		send_non_200_ack(msg,t);
		
		// TODO: set D timer if UDP
		t->reset_timer(STIMER_D, D_TIMER, bucket->get_id());
		
		goto pass_reply;
		
	    case TS_COMPLETED:
		// retransmit non-200 ACK
		retransmit(t);
	    default:
		goto end;
	    }
	} 
	else {
	    
	    // Positive final reply to INVITE transaction
	    switch(t->state){
		
	    case TS_CALLING:
	    case TS_PROCEEDING:
		// TODO:
		//  we should take care of 200 ACKs
		//    - on first reply:
		//      - save to-tag.
		//      - use route-set included in the INV req (if applicable).
		//      - save ACK for retransmitions.
		//    - compare to-tag on subsequent replies.
		//      - (if different): 
		//        - (generate new 200 ACK based on reply).
		//        - (send BYE (check for existing UAC trans)).
		//      - else:
		//        - re-transmit ACK.

		t->state  = TS_TERMINATED_200;
		t->clear_timer(STIMER_A);
		t->clear_timer(STIMER_B);

		t->reset_timer(STIMER_L, L_TIMER, bucket->get_id());

		t->to_tag.s = new char[to_tag.len];
		t->to_tag.len = to_tag.len;
		memcpy((void*)t->to_tag.s,to_tag.s,to_tag.len);
		
		send_200_ack(msg,t);

		goto pass_reply;
		
	    case TS_TERMINATED_200:
		
		if( (to_tag.len != t->to_tag.len) ||
		    (memcmp(to_tag.s,t->to_tag.s,to_tag.len) != 0) ){

		    // TODO: 
		    //   (this should be implemented in the UA)
		    //   we should send 200 ACK also here,
		    //   but this would mean that we should
		    //   also be sending a BYE also to quit
		    //   this dialog.
		    //
		    goto end;
		}

		retransmit(t);
		goto end;

	    default:
		goto end;
	    }
	}
    }
    else { // non-INVITE transaction

	// Final reply
	switch(t->state){
	    
	case TS_TRYING:
	case TS_CALLING:
	case TS_PROCEEDING:
	    
	    t->state = TS_COMPLETED;
	
	    t->clear_timer(STIMER_E);
	    // TODO: timer should be 0 if reliable transport
	    t->reset_timer(STIMER_K, K_TIMER, bucket->get_id());
	    
	    if(t->msg->u.request->method != sip_request::CANCEL)
		goto pass_reply;
	    else
		goto end;

	case TS_COMPLETED:
	    // Absorb reply retransmission (only if UDP)
	    goto end;
	    
	default:
	    goto end;
	}
    }

 pass_reply:
    assert(ua);
    ua->handle_sip_reply(msg);
 end:
    return 0;
}
Пример #10
0
void trans_layer::received_msg(sip_msg* msg)
{
#define DROP_MSG \
          delete msg;\
          return

    int err = parse_sip_msg(msg);
    DBG("parse_sip_msg returned %i\n",err);

    if(err){
	DBG("Message was: \"%.*s\"\n",msg->len,msg->buf);
	DBG("dropping message\n");
	DROP_MSG;
    }
    
    assert(msg->callid && get_cseq(msg));
    if(!msg->callid || !get_cseq(msg)){
	
	DBG("Call-ID or CSeq header missing: dropping message\n");
	DROP_MSG;
    }

    unsigned int  h = hash(msg->callid->value, get_cseq(msg)->num_str);
    trans_bucket* bucket = get_trans_bucket(h);
    sip_trans* t = NULL;

    bucket->lock();

    switch(msg->type){
    case SIP_REQUEST: 
	
	if((t = bucket->match_request(msg)) != NULL){
	    if(msg->u.request->method != t->msg->u.request->method){
		
		// ACK matched INVITE transaction
		DBG("ACK matched INVITE transaction\n");
		
		err = update_uas_request(bucket,t,msg);
		if(err<0){
		    DBG("trans_layer::update_uas_trans() failed!\n");
		    // Anyway, there is nothing we can do...
		}
		else if(err == TS_TERMINATED){
		
		    // do not touch the transaction anymore:
		    // it could have been deleted !!!
		       
		    // should we forward the ACK to SEMS-App upstream? Yes
		}
	    }
	    else {
		DBG("Found retransmission\n");
		retransmit(t);
	    }
	}
	else {

	    string t_id;
	    sip_trans* t = NULL;
	    if(msg->u.request->method != sip_request::ACK){
		
		// New transaction
		t = bucket->add_trans(msg, TT_UAS);

		t_id = int2hex(h).substr(5,string::npos) 
		    + ":" + long2hex((unsigned long)t);
	    }

	    bucket->unlock();
	    
	    //  let's pass the request to
	    //  the UA. 
	    assert(ua);
	    ua->handle_sip_request(t_id.c_str(),msg);

	    if(!t){
		DROP_MSG;
	    }
	    //Else:
	    // forget the msg: it will be
	    // owned by the new transaction
	    return;
	}
	break;
    
    case SIP_REPLY:

	if((t = bucket->match_reply(msg)) != NULL){

	    // Reply matched UAC transaction
	    
	    DBG("Reply matched an existing transaction\n");
	    if(update_uac_trans(bucket,t,msg) < 0){
		ERROR("update_uac_trans() failed, so what happens now???\n");
		break;
	    }
	    // do not touch the transaction anymore:
	    // it could have been deleted !!!
	}
	else {
	    DBG("Reply did NOT match any existing transaction...\n");
	    DBG("reply code = %i\n",msg->u.reply->code);
	    if( (msg->u.reply->code >= 200) &&
	        (msg->u.reply->code <  300) ) {
		
		bucket->unlock();
		
		// pass to UA
		assert(ua);
		ua->handle_sip_reply(msg);
		
		DROP_MSG;
	    }
	}
	break;

    default:
	ERROR("Got unknown message type: Bug?\n");
	break;
    }

    // unlock_drop:
    bucket->unlock();
    DROP_MSG;
}
Пример #11
0
void trans_layer::timer_expired(timer* t, trans_bucket* bucket, sip_trans* tr)
{
    int n = t->type >> 16;
    int type = t->type & 0xFFFF;

    switch(type){

    case STIMER_A:  // Calling: (re-)send INV

	n++;
	retransmit(tr->msg);
	tr->reset_timer((n<<16) | type, T1_TIMER<<n, bucket->get_id());
	break;
	
    case STIMER_B:  // Calling: -> Terminated

	tr->clear_timer(STIMER_B);
	if(tr->state == TS_CALLING) {
	    DBG("Transaction timeout!\n");
	    timeout(bucket,tr);
	}
	else {
	    DBG("Transaction timeout timer hit while state=0x%x",tr->state);
	}
	break;

    case STIMER_F:  // Trying/Proceeding: terminate transaction
	
	tr->clear_timer(STIMER_F);

	switch(tr->state) {

	case TS_TRYING:
	case TS_PROCEEDING:
	    DBG("Transaction timeout!\n");
	    timeout(bucket,tr);
	    break;
// 	case TS_TERMINATED_200:
// 	    bucket->remove_trans(tr);
// 	    break;
	}
	break;

    case STIMER_D:  // Completed: -> Terminated
    case STIMER_K:  // Completed: terminate transaction
    case STIMER_J:  // Completed: -> Terminated
    case STIMER_H:  // Completed: -> Terminated
    case STIMER_I:  // Confirmed: -> Terminated
    case STIMER_L:  // Terminated_200 -> Terminated
	
	tr->clear_timer(type);
	tr->state = TS_TERMINATED;
	bucket->remove_trans(tr);
	break;


    case STIMER_E:  // Trying/Proceeding: (re-)send request
    case STIMER_G:  // Completed: (re-)send response

	n++; // re-transmission counter

	//
	// in this stack, the transaction layer
	// takes care of re-transmiting the 200 reply
	// in a UAS INVITE transaction.
	//
	if(tr->type == TT_UAS){
	    
	    // re-transmit reply to INV
	    retransmit(tr);
	}
	else {

	    // re-transmit request
	    retransmit(tr->msg);
	}

	if(T1_TIMER<<n > T2_TIMER) {
	    tr->reset_timer((n<<16) | type, T2_TIMER, bucket->get_id());
	}
	else {
	    tr->reset_timer((n<<16) | type, T1_TIMER<<n, bucket->get_id());
	}
	break;

    default:
	ERROR("Invalid timer type %i\n",t->type);
	break;
    }
}