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; }
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);
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; }