Exemplo n.º 1
0
void TCP_Process_effective_close
   (
      TCB_STRUCT_PTR       tcb,     /* IN/OUT - TCP context */
      TCP_CFG_STRUCT_PTR   tcp_cfg  /* IN     - TCP layer data */
   )
{ /* Body */
   RTCSLOG_FNE2(RTCSLOG_FN_TCP_Process_effective_close, tcb->state);
    
   switch ( tcb->state ) {

      case SYN_RECEIVED:
         /* no data has been sent  */

      case ESTABLISHED:
         tcb->state = FINWAIT_1;
         TCP_Must_send_ack(tcb, tcp_cfg);
         break;

      case CLOSE_WAIT:
         tcb->state = LAST_ACK;
         TCP_Must_send_ack(tcb, tcp_cfg);
         break;

      default:
         RTCS_log_error(ERROR_TCP,
                             RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                             (uint_32)tcb->state,
                             (uint_32)tcb, 0);

         break;

   } /* End Switch */

    SOCK_select_signal(tcb->SOCKET, tcb->state);
   
    RTCSLOG_FNX1(RTCSLOG_FN_TCP_Process_effective_close);
} /* Endbody */
Exemplo n.º 2
0
HOSTENT_STRUCT  *DNS_query_resolver_task
   (
   unsigned char  *name,
   uint16_t     query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT        *message_head_ptr;
   DNS_MESSAGE_TAIL_STRUCT          *message_tail_ptr;
   HOSTENT_STRUCT                   *host_ptr = NULL;
   sockaddr_in                       addr;
   uint32_t                           local_sock;
   uint32_t                           qname_size;
   uint32_t                           buffer_size;
   uint16_t                           rlen;
   int32_t                            temp_size;
   int32_t                            error;
   unsigned char                            *temp_ptr;
   unsigned char                            *qname_ptr;
   unsigned char                            *buffer_ptr;



   /*
   ** If the size of this buffer is changed, also change the buffer size
   ** in the recvfrom() call near the bottom of this function
   */
   buffer_ptr = RTCS_mem_alloc_zero( DNS_MAX_UDP_MESSAGE_SIZE );
   if ( buffer_ptr == NULL ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                     0, 0, 0);
      return( NULL );
   }/* Endif */
   _mem_set_type(buffer_ptr, MEM_TYPE_DNS_UDP_MESSAGE);
   qname_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   if ( query_type == DNS_A ) {
       error = DNS_is_dotted_domain_name( name, qname_ptr );
       if ( error == RTCSERR_DNS_INVALID_NAME ||
            error == RTCSERR_DNS_INVALID_LOCAL_NAME ) {
          _mem_free(buffer_ptr);
          return( NULL );
       }/* Endif */
   } else {
      if ( query_type == DNS_PTR ) {
         error = DNS_insert_IP_query( name, qname_ptr );
         if ( error == RTCSERR_DNS_INVALID_IP_ADDR ) {
            _mem_free(buffer_ptr);
            return( NULL );
         }/* Endif */
      } else {
         _mem_free(buffer_ptr);
         return( NULL );
      } /* Endif */
   } /* Endif */

   local_sock = socket(AF_INET, SOCK_DGRAM, 0);

   if ( local_sock == RTCS_HANDLE_ERROR ) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_OPEN_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Local address  */
   addr.sin_family       = AF_INET;
   addr.sin_port         = 0;
   addr.sin_addr.s_addr  = INADDR_ANY;

   error =  bind(local_sock, &addr, sizeof(addr));
   if (error != RTCS_OK) {
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_BIND_SOCKET,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   /* set up buffer for sending query.   */
   message_head_ptr = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr;

   mqx_htons(message_head_ptr->ID, 0);
   mqx_htons(message_head_ptr->CONTROL, DNS_STANDARD_QUERY);
   mqx_htons(message_head_ptr->QDCOUNT, DNS_SINGLE_QUERY);
   mqx_htons(message_head_ptr->NSCOUNT, 0);
   mqx_htons(message_head_ptr->ARCOUNT, 0);
   mqx_htons(message_head_ptr->ANCOUNT, 0);

   qname_size = strlen((char *)qname_ptr );
   /* Need to include the last '\0' character as well */
   qname_size++;

   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT )
                          + qname_size;

   message_tail_ptr = (DNS_MESSAGE_TAIL_STRUCT *)temp_ptr;

   mqx_htons(message_tail_ptr->QTYPE, query_type);
   mqx_htons(message_tail_ptr->QCLASS, DNS_IN);

   buffer_size = sizeof(DNS_MESSAGE_HEADER_STRUCT) + qname_size
                 + sizeof(DNS_MESSAGE_TAIL_STRUCT);

    /* Remote address, DNS_Resolver currently uses port 1024 */
   addr.sin_port        = DNS_RESOLVER_PORT;
   addr.sin_addr.s_addr = DNS_RESOLVER_IP_ADDR;

   rlen = sizeof(addr);

   /* Send the buffer to the resolver for making a query */
   error = sendto(local_sock, buffer_ptr, buffer_size, 0, &addr, rlen);
   if (error == RTCS_ERROR) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_SEND_QUERY,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   }/* Endif */

   /* Get the response from the resolver, if none received, return NULL */
   error = (uint32_t)RTCS_selectset( &local_sock, 1, DNS_QUERY_TIMEOUT );
   if ( !error || error == RTCS_ERROR ) {
      shutdown(local_sock, FLAG_ABORT_CONNECTION);
      RTCS_log_error(ERROR_DNS, RTCSERR_DNS_NO_RESPONSE_FROM_RESOLVER,
                     0, 0, 0);
      _mem_free(buffer_ptr);
      return( NULL );
   } /* Endif */

   temp_size = recvfrom(local_sock, buffer_ptr, DNS_MAX_UDP_MESSAGE_SIZE,
                        0, &addr, &rlen);
   if ( temp_size == RTCS_ERROR ) {
     shutdown(local_sock, FLAG_ABORT_CONNECTION);
     RTCS_log_error(ERROR_DNS, RTCSERR_DNS_PACKET_RECEPTION_ERROR,
                    0, 0, 0);
     _mem_free(buffer_ptr);
     return( NULL );
   }/* Endif */

   host_ptr = DNS_parse_UDP_response(buffer_ptr, name, query_type);
   shutdown(local_sock, FLAG_ABORT_CONNECTION);
   _mem_free(buffer_ptr);
   return( host_ptr );

} /* Endbody */
Exemplo n.º 3
0
HOSTENT_STRUCT  *DNS_parse_UDP_response
   (
   unsigned char    *buffer_ptr,
   unsigned char    *name_ptr,
   uint16_t       query_type
   )

{  /* Body */

   DNS_MESSAGE_HEADER_STRUCT            *message_head_ptr = NULL;
   DNS_RESPONSE_RR_MIDDLE_STRUCT        *answer_middle;
   INTERNAL_HOSTENT_STRUCT              *host_ptr = &RTCS_HOST;
   unsigned char                                *answer_ptr;
   unsigned char                                *answer_tail;
   unsigned char                                *temp_ptr;
   uint16_t                               response_length, answer_type,
      name_size, number_of_answers, num_queries;
   uint32_t                               i, name_index = 0;
   uint32_t                               j = 0;
   uint32_t                               k = 0;
   uint32_t                               buffer_size;
   uint32_t                              *addr_ptr;
   bool                               unknown_answer_type = FALSE;

   message_head_ptr  = (DNS_MESSAGE_HEADER_STRUCT *)buffer_ptr;
   buffer_size       = sizeof(DNS_MESSAGE_HEADER_STRUCT);
   temp_ptr = buffer_ptr + sizeof( DNS_MESSAGE_HEADER_STRUCT );

   /* Zero the global HOSTENT_STRUCT */
   _mem_zero((char *)host_ptr, sizeof(INTERNAL_HOSTENT_STRUCT));

   /* Get the number of queries. */
   num_queries = mqx_ntohs(message_head_ptr->QDCOUNT);
   for (i = 0; i < num_queries; i++) {
      name_size = 0;
      while( (mqx_ntohc(temp_ptr) != '\0') &&
         name_size < DNS_MAX_CHARS_IN_NAME ) {
         name_size = name_size + mqx_ntohc(temp_ptr) + 1;
         temp_ptr  = temp_ptr  + mqx_ntohc(temp_ptr) + 1;
      } /* Endwhile */
      /* To include the terminating NULL char */
      name_size++;
      buffer_size += (name_size + sizeof(DNS_MESSAGE_TAIL_STRUCT));
      temp_ptr    += (1 + sizeof(DNS_MESSAGE_TAIL_STRUCT));
   } /* Endfor */

   number_of_answers = mqx_ntohs(message_head_ptr->ANCOUNT);
   if (number_of_answers > DNS_MAX_NAMES ) {
      number_of_answers = DNS_MAX_NAMES;
   } /* Endif */

   host_ptr->HOSTENT.h_aliases   = &host_ptr->ALIASES[0];
   host_ptr->HOSTENT.h_addr_list = (char **)&host_ptr->ADDRESSES[0];
   host_ptr->ADDRESSES[0]        = NULL;
   host_ptr->HOSTENT.h_name      = NULL;
   host_ptr->HOSTENT.h_length    = sizeof( _ip_address );

   for (i = 0; (i < number_of_answers) && (j < DNS_MAX_ADDRS) &&
       (k < DNS_MAX_NAMES); i++ )
   {
      answer_ptr = temp_ptr;
      name_size  = 0;

      while( (mqx_ntohc(temp_ptr) != '\0') &&
             name_size < DNS_MAX_CHARS_IN_NAME &&
             !(mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK)) {
         name_size += mqx_ntohc(temp_ptr);
         temp_ptr += mqx_ntohc(temp_ptr) + 1;
      } /* Endwhile */

      if ( mqx_ntohc(temp_ptr) & DNS_COMPRESSED_NAME_MASK ) {
         temp_ptr++;
      }/* Endif */

      temp_ptr++;
      answer_middle   = (DNS_RESPONSE_RR_MIDDLE_STRUCT *)temp_ptr;
      response_length = mqx_ntohs(answer_middle->RDLENGTH);
      answer_type     = mqx_ntohs(answer_middle->TYPE);
      temp_ptr       += sizeof(DNS_RESPONSE_RR_MIDDLE_STRUCT);
      answer_tail     = temp_ptr;
      temp_ptr       += response_length;

      switch ( answer_type ) {

         case DNS_A:
            if ( host_ptr->HOSTENT.h_name == NULL ) {
               host_ptr->HOSTENT.h_name =
                  (char *)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_ptr, name_index );
               name_index++;
            } /* Endif */

            RTCS_HOST_ADDRS[j] = mqx_ntohl((unsigned char *)answer_tail);
            /*
            ** j is used in case BOTH CNAME and A data is received.  If CNAME
            ** answer is first, will write into wrong address space if using
            ** i.
            */
            host_ptr->ADDRESSES[j] = &RTCS_HOST_ADDRS[j];
            j++;
            /*
            ** This is to assure that the first IP address used is the first
            ** one that was given
            */
            host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            break;

         case DNS_PTR:
            if (query_type == DNS_PTR) {
               if (host_ptr->HOSTENT.h_name != NULL) {
                  host_ptr->ALIASES[k] = host_ptr->HOSTENT.h_name;
                  k++;
               } /* Endif */
               host_ptr->HOSTENT.h_name =
                  (char *)DNS_parse_answer_name_to_dotted_form(
                  buffer_ptr, answer_tail, name_index );
               name_index++;
               addr_ptr = RTCS_mem_alloc_zero( sizeof( _ip_address ));
               if ( addr_ptr == NULL ) {
                  RTCS_log_error(ERROR_DNS, RTCSERR_DNS_UNABLE_TO_ALLOCATE_MEMORY,
                                 0, 0, 0);
                  return( NULL );
               }/* Endif */

               *addr_ptr = *((_ip_address *)name_ptr);
               host_ptr->ADDRESSES[j] = addr_ptr;
               j++;
               host_ptr->IP_address = *host_ptr->ADDRESSES[0];
            } else {
               host_ptr->ALIASES[k] = (char *)
                     DNS_parse_answer_name_to_dotted_form( buffer_ptr,
                     answer_tail, name_index );
               name_index++;
               k++;
            } /* Endif */
            break;

         case DNS_CNAME:
            /* the k is used for ALIASES as the j is used for ADDRESSES */
            host_ptr->ALIASES[k] = (char *)
               DNS_parse_answer_name_to_dotted_form(
               buffer_ptr, answer_tail, name_index );
            name_index++;
            k++;
            break;

         default:
            unknown_answer_type = TRUE;
      } /* Endswitch */

      if ( unknown_answer_type == TRUE ) {
         break;
      }/* Endif */

      host_ptr->ADDRESSES[j]       = NULL;
      host_ptr->ALIASES[k]         = NULL;
      host_ptr->HOSTENT.h_addrtype = mqx_ntohs(answer_middle->CLASS);

   } /* Endfor */

   if ( number_of_answers == 0 ) {
      return( NULL );
   } /* Endif */

   return( &RTCS_HOST.HOSTENT );

} /* Endbody */
Exemplo n.º 4
0
void TCP_Process_close
   (
      TCP_PARM_PTR   req_ptr     /* IN/OUT - the open request */
   )
{ /* Body */
   TCP_CFG_STRUCT_PTR   tcp_cfg;
   TCB_STRUCT_PTR       tcb;
   int_32               reply = RTCS_OK;

   tcp_cfg = RTCS_getcfg(TCP);
   tcb = req_ptr->TCB_PTR;

   if ( tcb == NULL ) { 
      RTCSCMD_complete(req_ptr, RTCSERR_TCP_CONN_RLSD);
      return;
   } 

   IF_TCP_STATS_ENABLED(tcp_cfg->STATS.ST_CONN_CLOSED++);

   if ( tcb->VALID != TCB_VALID_ID ) {
      reply = RTCSERR_TCP_CONN_RLSD;
      RTCS_log_error( ERROR_TCP,
                           RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                           (uint_32)tcb,
                           (uint_32)tcb->state,
                           1 );

   } else if ( tcb->state == CLOSED ) {

      /* This should be the standard case if the other side aborted. */
      TCP_Process_release(tcb, tcp_cfg);

   } else if ( (tcb->status & TCPS_FINTOSEND) != 0 ) {

      /* Upper layer must have already given us a tcpCLOSE, so we
       *    can generate an error here. */
      reply = RTCSERR_TCP_CONN_CLOSING;

   } else {

      switch ( tcb->state ) {

         case LISTEN:
         case SYN_SENT:
            TCP_Close_TCB(tcb, RTCS_OK, tcp_cfg);
          case BOUND:
            TCP_Process_release(tcb, tcp_cfg);
            break;

         case SYN_RECEIVED:
            /* no data has been sent */

         case ESTABLISHED:
         case CLOSE_WAIT:

            TCP_Event(tcb,TCPS_FINTOSEND);

            /*  We can only effectively close if all data has been sent,
             *   allowing us to send a FIN immediately; otherwise closing
             *   is delayed (TCPS_FINTOSEND indicates that connection should
             *   be closed as soon as all data is sent)
             */
            if ( tcb->sndnxt == (tcb->sndbufseq + tcb->sndlen) ) {
               TCP_Process_effective_close(tcb, tcp_cfg);
            } else {
               /*
               **  Have to kick ourselves into sending the outstanding
               **  data or we'll sit here forever if the other side is
               **  just waiting.  This would happen if we send w/o PUSH
               **  just before closing.
               */
               TCP_Must_send_ack(tcb, tcp_cfg);
            } /* Endif */

            break;

         default:
            /*  we shouldn't reach here, but jic...  */
            RTCS_log_error( ERROR_TCP,
                                 RTCSERR_TCP_BAD_STATE_FOR_CLOSE,
                                 (uint_32)tcb,
                                 (uint_32)tcb->state,
                                 2);

            reply = RTCSERR_TCP_NOT_CONN;
            break;

      } /* End Switch */

   } /* Endif */

   /* The socket will be freed as soon as we return to shutdown() */
   if (tcb->VALID == TCB_VALID_ID) {
       tcb->SOCKET = 0;
   } /* Endif */

   RTCSCMD_complete(req_ptr, reply);

} /* Endbody */
Exemplo n.º 5
0
uint_32 RTCS_create
   (
      void
   )
{ /* Body */
   RTCS_DATA_PTR              RTCS_data_ptr;
   SOCKET_CONFIG_STRUCT_PTR   socket_cfg_ptr;
   uint_32                    error;

   /*
   ** Check and see if this is the first time we have initialized,
   */
   if (RTCS_get_data() != NULL) {
      return RTCSERR_INITIALIZED;
   } 
//
   RTCS_data_ptr = RTCS_mem_alloc_system_zero(sizeof(RTCS_DATA));

   if (RTCS_data_ptr == NULL)  {
      error = RTCSERR_OUT_OF_MEMORY;
   } else {

   _mem_set_type(RTCS_data_ptr, MEM_TYPE_RTCS_DATA);

   RTCS_set_data(RTCS_data_ptr);

   /*
   ** Initialize socket state
   */
   socket_cfg_ptr = RTCS_mem_alloc_system_zero(sizeof(SOCKET_CONFIG_STRUCT));

      if (socket_cfg_ptr == NULL)  {
         error =  RTCSERR_OUT_OF_MEMORY;
      } else {
         _mem_set_type(socket_cfg_ptr, MEM_TYPE_SOCKET_CONFIG_STRUCT);
      
         socket_cfg_ptr->INITIALIZED = TRUE;
         socket_cfg_ptr->SOCKET_HEAD = NULL;
         socket_cfg_ptr->SOCKET_TAIL = NULL;
         RTCS_mutex_init(&socket_cfg_ptr->SOCK_MUTEX);
         RTCS_setcfg(SOCKET, socket_cfg_ptr);

   /*
   ** Initialize global data
   */
   _IP_forward    = FALSE;
   _TCP_bypass_rx = FALSE;
   _TCP_bypass_tx = FALSE;

   RTCS_data_ptr->VERSION            = RTCS_VERSION;
#if RTCSCFG_LOG_SOCKET_API||RTCSCFG_LOG_PCB
   RTCS_data_ptr->RTCS_LOG_PROTCOUNT = RTCSLOG_PROT_MAX;
   RTCSLOG_disable(RTCS_LOGCTRL_ALL);
#endif
   RTCS_data_ptr->TCPIP_qid = RTCS_msgq_get_id(0,TCPIP_QUEUE);

         /*
         ** Create a pool of buffers for use in communicating to the TCP/IP task.
         */
         RTCS_data_ptr->TCPIP_msg_pool = RTCS_msgpool_create(sizeof(TCPIP_MESSAGE),
            _RTCS_msgpool_init, _RTCS_msgpool_grow, _RTCS_msgpool_max);
         if (RTCS_data_ptr->TCPIP_msg_pool == MSGPOOL_NULL_POOL_ID) {
            RTCS_log_error( ERROR_TCPIP, RTCSERR_CREATE_POOL_FAILED, 0, 0, 0);
            error =  RTCSERR_CREATE_POOL_FAILED;
         } else {
            /*
            ** Create the socket partition
            */
            RTCS_data_ptr->RTCS_socket_partition = RTCS_part_create(sizeof(SOCKET_STRUCT),
              _RTCS_socket_part_init, _RTCS_socket_part_grow, _RTCS_socket_part_max, NULL, NULL);
            if (RTCS_data_ptr->RTCS_socket_partition == 0) {
               RTCS_log_error(ERROR_RTCS, RTCSERR_CREATE_PARTITION_FAILED, 0, 0, 0);
               error = RTCSERR_CREATE_PARTITION_FAILED;
            } else {
               /*
               ** Create TCPIP task
               */
               error = RTCS_task_create("TCP/IP", _RTCSTASK_priority, _RTCSTASK_stacksize, TCPIP_task, NULL);
               if (error) {
                  RTCS_part_destroy(RTCS_data_ptr->RTCS_socket_partition);
               }
            }
            if (error) {
               RTCS_msgpool_destroy( RTCS_data_ptr->TCPIP_msg_pool );
            }     
         }
         if (error) {
            RTCS_setcfg(SOCKET, NULL);
            _mem_free(socket_cfg_ptr);
         }
      }
      if (error) {
         RTCS_set_data(NULL);
         _mem_free(RTCS_data_ptr);
      }
   }
   
   return error;
            
} /* Endbody */