Пример #1
0
void u2f_hid_request(struct u2f_hid_msg* req)
{
	uint8_t* payload = req->pkt.init.payload;
	static int8_t last_seq = -1;
	struct CID* cid = get_cid(req->cid);


	if (cid != NULL)
	{
		refresh_cid(cid);
	}
	else if (req->cid == U2FHID_BROADCAST)
	{

	}
	else
	{
		// Ignore CID's we did not allocate.
		//u2f_printlx("ignoring pkt ",1,req->cid);
		return;
	}

	// ignore if we locked to a different cid
	if(hid_is_locked())
	{
		if (!hid_is_lock_cid(cid))
		{
			stamp_error(hid_layer.current_cid, ERR_CHANNEL_BUSY);
			return;
		}
	}

	hid_layer.state = (u2f_hid_busy()) ? HID_BUSY : HID_READY;

	switch(hid_layer.state)
	{
		case HID_READY:
			if (req->pkt.init.cmd & TYPE_INIT)
			{
				if (U2FHID_LEN(req) > U2FHID_MAX_PAYLOAD_SIZE)
				{
					//u2f_prints("length too big\r\n");
					stamp_error(req->cid, ERR_INVALID_LEN);
					return;
				}
				u2f_hid_reset_packet();
				hid_layer.current_cid = req->cid;
				hid_layer.current_cmd = req->pkt.init.cmd;
				hid_layer.last_buffered = get_ms();
				last_seq = -1;

			}
			else
			{
				stamp_error(req->cid, ERR_INVALID_CMD);
				u2f_prints("ERR_INVALID_CMD\r\n");
				return;
			}

			break;
		case HID_BUSY:
			// buffer long requests
			if (req->cid == hid_layer.current_cid)
			{
				if (req->pkt.init.cmd & TYPE_INIT)
				{
					u2f_hid_reset_packet();
					u2f_hid_request(req);
					return;
				}

				hid_layer.last_buffered = get_ms();

				// verify packets arrive in ascending order
				if (last_seq + 1 != req->pkt.cont.seq)
				{
					u2f_hid_reset_packet();
					stamp_error(hid_layer.current_cid, ERR_INVALID_SEQ);
					return;
				}
				last_seq = req->pkt.cont.seq;

			}
			else if (U2FHID_TIMEOUT(&hid_layer))
			{
				// return timeout error for old channel and run again for new channel
				//u2f_prints("timeout, switching\r\n");
				hid_layer.state = HID_READY;
				u2f_hid_reset_packet();
				stamp_error(hid_layer.current_cid, ERR_MSG_TIMEOUT);
				u2f_hid_request(req);
				return;
			}
			else
			{
				// Current application may not be interrupted
				stamp_error(req->cid, ERR_CHANNEL_BUSY);
				return;
			}
			break;

	}

	hid_u2f_parse(req);
	return;
}
Пример #2
0
int send (int l, int va, int s){
  int c = get_cid ();
  if (l < 0 || l > MAX_CHAN) 
    return ERROR;
  <@$\intp$@>fifoq_pre_insrt (l);
Пример #3
0
void u2f_hid_request(struct u2f_hid_msg* req)
{
	static int8_t last_seq;
	struct CID* cid = NULL;

	cid = get_cid(req->cid);

	// Error checking
	if ((U2FHID_IS_INIT(req->pkt.init.cmd)))
	{
		if (U2FHID_LEN(req) > 7609)
		{
			stamp_error(req->cid, ERR_INVALID_LEN);
			return;
		}
		if (req->pkt.init.cmd != U2FHID_INIT && req->cid != hid_layer.current_cid && u2f_hid_busy())
		{
			stamp_error(req->cid, ERR_CHANNEL_BUSY);
			return;
		}
	}
	else if (cid == NULL || !cid->busy)
	{
		// ignore random cont packets
		return;
	}

	if (!req->cid)
	{
		stamp_error(req->cid, ERR_SYNC_FAIL);
		return;
	}



	if (req->cid == U2FHID_BROADCAST)
	{
		if (!(req->pkt.init.cmd == U2FHID_INIT))
		{
			stamp_error(req->cid, ERR_SYNC_FAIL);
			return;
		}
		cid = &BROADCAST_CID;
		BROADCAST_CID.cid = U2FHID_BROADCAST;
	}
	else if (U2FHID_IS_INIT(req->pkt.init.cmd) && cid == NULL)
	{
		add_new_cid(req->cid);
		cid = get_cid(req->cid);
		if (cid == NULL)
		{
			return;
		}
		cid->busy = 0;
	}




	// Reset init packets
	if (req->pkt.init.cmd == U2FHID_INIT)
	{
		cid->busy = 0;
	}

	hid_layer.current_cid = req->cid;
	hid_layer.last_buffered = get_ms();

	cid->last_used = get_ms();


	// ignore if we locked to a different cid
#ifdef U2F_SUPPORT_HID_LOCK
	if(hid_is_locked() && req->pkt.init.cmd != U2FHID_INIT)
	{
		if (!hid_is_lock_cid(req->cid))
		{
			stamp_error(req->cid, ERR_CHANNEL_BUSY);
			return;
		}
	}
#endif

	if ((req->pkt.init.cmd & TYPE_INIT) && !cid->busy)
	{
		cid->last_cmd = req->pkt.init.cmd;
		hid_layer.current_cmd = req->pkt.init.cmd;
		last_seq = -1;

	}
	else
	{


		// verify packets arrive in ascending order
		hid_layer.last_buffered = get_ms();
		if (last_seq + 1 != req->pkt.cont.seq)
		{
			stamp_error(hid_layer.current_cid, ERR_INVALID_SEQ);
			u2f_hid_reset_packet();
			return;
		}
		last_seq = req->pkt.cont.seq;

		hid_layer.current_cmd = cid->last_cmd;

	}

	cid->busy = hid_u2f_parse(req);

}
/*
 * ******************************************* 
 *  Function: handle_transport_layer_packet  
 *
 *  Description: 
 *
 *  handle a transport layer 
 *  packet. Core transport layer handling 
 *  function , all the other funcitons 
 *  were written to support this big guy 
 *  
 *  Parameters: 
 *     buffer - packet buffer 
 *     src_id  - Source id 
 *     dest_id - Destination id 
 *
 * ******************************************* 
 */
void handle_transport_layer_packet( void * buffer , int src_id , int dest_id )
{

      
        int packet_type; 
        int requested_mtu; 
        int seq_no; 
        int connect_id; 
        void *realloc_buffer;
        int win_size ;	
	void *packet_data;
        int cid_seq_no; 	
        int current_sender_id; 
	int current_cid_state; 
	int sender_id ;
        char *realloc_buf_ptr; 	
	int max_connections_permitted = get_state(&__max_connections);
	packet_type = get_packet_type(buffer);

	switch(packet_type)
	{
		case CONTROL_CONNECT:
			requested_mtu = get_requested_mtu(buffer);
		        connect_id  =allocate_sender(max_connections_permitted);
			sender_id  = get_sender_id(buffer);
		        if ( connect_id  <  max_connections_permitted)
			{
                             
		              init_state(&__session_tab.cid_info[connect_id].curr_state);
		              set_state(&__session_tab.cid_info[connect_id].curr_state ,STATE_CONNECTED);
		              __session_tab.cid_info[connect_id].sequence_number = 0;  
		              __session_tab.cid_info[connect_id].buf_len = 0;  	
			        
                              send_connect_ack(src_id  , requested_mtu , connect_id,sender_id); 

			}
		        else
		        {
                              fprintf(stderr ,"%s", "\n Connection not possilbe  all slots full \n"); 
                              
		        }	
                        break;
		case CONTROL_ACK:
                        seq_no = get_sequence_number(buffer);
                        current_sender_id = get_sender_id(buffer);
			connect_id  = get_cid(buffer); 
			sender_buffer[current_sender_id].seq_no = seq_no; 
		        sender_buffer[current_sender_id].response_code = CONTROL_ACK; 
			sender_buffer[current_sender_id].connection_id = connect_id; 
                        break;
		case CONTROL_DATA:
		   {	
                       
			fprintf(stderr,"DATA packet received  ... ");    
		        connect_id  = get_cid(buffer);
		        seq_no = get_sequence_number(buffer);
			sender_id = get_sender_id(buffer);
                        cid_seq_no = __session_tab.cid_info[connect_id].sequence_number;
                        current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); 			
			fprintf(stderr,"\n seq no = %d cid seq no = %d window size = %d  CID = %d" , seq_no , cid_seq_no , get_window_size(buffer) , connect_id);
		        /* are we getting the next sequnce number  & we are connected */
			if( (  seq_no == cid_seq_no + 1 ) )
			{
                              win_size = get_window_size(buffer); 
		              realloc_buffer = malloc(win_size + __session_tab.cid_info[connect_id].buf_len);
		              if ( __session_tab.cid_info[connect_id].buf_len >  0  && ( current_cid_state != STATE_CLOSE)) 
			      {
			              memcpy(realloc_buffer,__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len);
				      realloc_buf_ptr = (char *) realloc_buffer + __session_tab.cid_info[connect_id].buf_len ;
				      packet_data    = (char *) buffer + TRASPORT_LAYER_SIZE ;  
				      memcpy(realloc_buf_ptr,packet_data , win_size);
				      __session_tab.cid_info[connect_id].buf_len += win_size; 
				      free( __session_tab.cid_info[connect_id].data_buf); 
				      __session_tab.cid_info[connect_id].data_buf = realloc_buffer;
                                      __session_tab.cid_info[connect_id].sequence_number++;
				      send_ack_request(src_id,seq_no,sender_id) ;   
		              }	     
			      else
			      {

				      packet_data    = (char *) buffer + TRASPORT_LAYER_SIZE ;  
				      memcpy(realloc_buffer,packet_data , win_size); 
				      __session_tab.cid_info[connect_id].buf_len += win_size; 
				      __session_tab.cid_info[connect_id].data_buf = realloc_buffer;
                                      __session_tab.cid_info[connect_id].sequence_number++;
				      send_ack_request(src_id,seq_no,sender_id) ;  

			      } 
                             
			}
		        else  if (  seq_no == cid_seq_no   )
			{
			        send_ack_request(src_id,seq_no,sender_id) ;   

			
			}
			else
			{
                            fprintf(stderr , "%s" , "\n Packet out of sequence number / duplicate  discarded \n ");  

			}	
                      }     
		      break; 

		case CONTROL_FIN:
		      fprintf(stderr ,"\n fin received  "); 
                      connect_id  = get_cid(buffer);
		      sender_id   = get_sender_id(buffer);
		      current_cid_state = get_state(&__session_tab.cid_info[connect_id].curr_state); 			
                      if ( current_cid_state  == STATE_CONNECTED )
		      {  
                              nfd_buffer_receved(__session_tab.cid_info[connect_id].data_buf,__session_tab.cid_info[connect_id].buf_len);
		              free(__session_tab.cid_info[connect_id].data_buf);
		              __session_tab.cid_info[connect_id].buf_len = 0 ; 
 		      }
		      else
		      {

                               set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_FIN); 	
		      }
		      send_ack_request(src_id,0,sender_id); 
		      break;

		case  CONTROL_CLOSE:
                      connect_id  = get_cid(buffer);
		      set_state(&__session_tab.cid_info[connect_id].curr_state,STATE_CLOSE);
                      deallocate_connection(connect_id);
		      fprintf(stderr , "\nRecevied close packet "); 
		      break;

		case CONTROL_CONNECT_ACK:
	               seq_no = get_sequence_number(buffer);
                       current_sender_id = get_sender_id(buffer);
		       connect_id  = get_cid(buffer); 
		       sender_buffer[current_sender_id].response_code = CONTROL_CONNECT_ACK;
		       sender_buffer[current_sender_id].mtu_possible = get_window_size(buffer);  
		       sender_buffer[current_sender_id].connection_id = connect_id; 
	               fprintf(stderr , "\n Recieved control connect ack  sender id %d  mtu_possible  %d " ,current_sender_id, sender_buffer[current_sender_id].mtu_possible );  
 	       
 	               break; 

                default:
		       /* None of the known control types */
		       /* dropping packet */
		      fprintf(stderr,"\n Not one of the known packet types, Type = %d " , packet_type ); 
		      break; 

	}

}
void overlay_loop()
{
	slothSock sock;
	bool discon = false;

	std::string cid;
	std::wstring clientname;
	std::vector<std::wstring> name_list;
	std::vector<bool> talking_list;
	std::vector<std::string> schandlerid;

	while(true)
	{
		while(pause)
		{
			psleep(200);
		}
		//clear vectors
		name_list.clear();
		talking_list.clear();
		schandlerid.clear();

		if(get_TS3_enabled())
		{
			//blog(LOG_WARNING, "connect");
			if(connect(sock, discon) == 0)
			{
				//blog(LOG_WARNING, "authorise");
				if(authorise(sock, discon) == 0)
				{
					if(discon)
					{
						discon = false;
					}
					//Get Channel client list and talking state
					//blog(LOG_WARNING, "get_cid");
					if(get_cid(sock, cid) == 0)
					{
						//blog(LOG_WARNING, "get_channelclientlist");
						get_channelclientlist(sock, cid, name_list, talking_list);
						//names = name_list;
						//talking = talking_list;
					}
					//get own name
					//blog(LOG_WARNING, "get_schandlerid");
					if(get_schandlerid(sock, schandlerid) == 0)
					{
						//blog(LOG_WARNING, "notifyregister");
						if(notifyregister(sock, schandlerid[0]) == 0)
						{
							//blog(LOG_WARNING, "clientname_from_uid");
							clientname_from_uid(sock, clientname);
							own_name = clientname;
						}
					}
				}
				sock.closeConnection();
			}
		}
		names = name_list;
		talking = talking_list;
		psleep(200);
	}
	return;
}