void unabto_dns_fallback_data_get_response(unabto_dns_fallback_session* session, unabto_dns_fallback_response_header* header, uint8_t* begin, uint8_t* end)
{
    if (session->state == UDFS_OPEN) {
        uint32_t host;
        uint16_t port;
        uint16_t moreData;
        uint8_t* data;
        uint16_t dataLength;
        READ_FORWARD_U32(host, begin);
        READ_FORWARD_U16(port, begin);
        READ_FORWARD_U16(moreData, begin);
        data = begin;
        dataLength = header->length - 13;
        if (header->status == UDF_STATUS_OK && dataLength > 0) {
            session->recvEp.addr = host;
            session->recvEp.port = port;
            memcpy(session->recvBuffer, data, header->length);
            session->recvState = UDF_RECV_HAS_PACKET;
            session->recvLength = dataLength;
        } else if (header->status == UDF_STATUS_TIMEOUT) {
            //nabtoSetFutureStamp(&session->recvTimeout, 0);
        } else if (header->status == UDF_STATUS_INVALID_SESSION) {
            session->state = UDFS_SESSION_OPENING;
        }
    }
}
Example #2
0
bool handle_syslog_config(struct unabto_payload_packet* payload) {
#if NABTO_ENABLE_DEBUG_SYSLOG_CONFIG
    uint8_t flags;
    uint8_t facility;
    uint16_t port;
    uint32_t ip;
    uint32_t expire;
    uint8_t* pattern;
    uint16_t patternLength;
    bool enabled;
    const uint8_t* ptr;
    if (payload->length < (NP_PAYLOAD_SYSLOG_CONFIG_SIZE_WO_STRINGS + 2)) {
        NABTO_LOG_ERROR(("Syslog config packet too short"));
        return false;
    }

    ptr = payload->dataBegin;

    READ_FORWARD_U8(flags, ptr);
    READ_FORWARD_U8(facility, ptr);
    READ_FORWARD_U16(port, ptr);
    READ_FORWARD_U32(ip, ptr);
    READ_FORWARD_U32(expire, ptr);
    READ_FORWARD_U16(patternLength, ptr);
    pattern = (uint8_t*)ptr;
    
    if (payload->length < (NP_PAYLOAD_SYSLOG_CONFIG_SIZE_WO_STRINGS + 2 + patternLength)) {
        NABTO_LOG_ERROR(("syslog packet log settings string too long"));
        return false;
    }

    enabled = flags & NP_PAYLOAD_SYSLOG_FLAG_ENABLE;

    return unabto_debug_syslog_config(enabled, facility, ip, port, expire, pattern, patternLength);
#else
    return false;
#endif
}
Example #3
0
void handle_command(uint8_t* packet, uint16_t packetLength)
{
  uint8_t command;

  READ_FORWARD_U8(command, packet);
  packetLength -= 1;

  switch (command)
  {
    // handle notification from the gateway
    case NSLP_COMMAND_NOTIFICATION:
    {
      uint16_t notificationId;

      READ_FORWARD_U16(notificationId, packet);

      notification(notificationId, packet);
    }
      break;

      // application events
    case NSLP_COMMAND_QUERY_REQUEST:
    {
      nslp_query* query;

      for (query = queries; query < (queries + NSLP_MAXIMUM_CONCURRENT_QUERIES); query++) // find idle query slot
      {
        if (query->state == NSLP_QUERY_STATE_IDLE)
        {
          uint8_t* p = packet;
          uint32_t flags;
          uint16_t readBufferLength;
          unabto_buffer readBufferStore;
          unabto_qury_request readBuffer;
          nslp_query_status status;

          memset(query, 0, sizeof(nslp_query));

          READ_FORWARD_U32(flags, p);
          if (flags & NSLP_COMMAND_QUERY_REQUEST_FLAG_IS_LOCAL)
          {
            query->isLocal = true;
          }

          if (flags & NSLP_COMMAND_QUERY_REQUEST_FLAG_CLIENT_ID_PRESENT)
          {
            query->clientId = (const char*)p; // read client id
            while (*p++); // skip past client id and zero-termination
          }

          if (flags & NSLP_COMMAND_QUERY_REQUEST_FLAG_RESPONSE_CAPACITY_PRESENT)
          {
            READ_FORWARD_U16(gatewayResponseCapacity, p);
          }

          READ_FORWARD_U32(query->queryId, p);

          readBufferLength = packetLength - (p - packet);
          buffer_init(&readBufferStore, p, readBufferLength);
          unabto_query_request_init(&readBuffer, &readBufferStore);

          query->state = NSLP_QUERY_STATE_ACTIVE;

          status = begin_nslp_query(query, &readBuffer); // call application query handler

          query->clientId = NULL; // only valid during the NSLP_COMMAND_QUERY_REQUEST so clear it now

          send_query_response(0, status, NULL, 0);

          if (status != NSLP_QUERY_STATUS_OK)
          {
            query->state = NSLP_QUERY_STATE_IDLE;
          }
          break;
        }
      }
    }
      break;

    case NSLP_COMMAND_QUERY_RESPONSE_CAPACITY:
      break;

    case NSLP_COMMAND_QUERY_DROP:
      break;
  }
}
Example #4
0
void nabto_stream_event(nabto_connect*       con,
                        nabto_packet_header* hdr,
                        uint8_t*             info, //WINDOW payload with payload header
                        uint8_t*             start,
                        int                  dlen,
                        uint8_t*             sackStart,
                        uint16_t             sackLength)
{
    struct nabto_win_info  win;
    struct nabto_stream_s* stream;
    struct nabto_stream_sack_data sackData;
    uint16_t len;

    // We must have a WINDOW payload to continue.
    if (!info) {
        NABTO_LOG_ERROR(("Stream %i, Packet has no WINDOW payload!", hdr->tag));
        return;
    }
    
    READ_U16(len, info + 2);
    if (!nabto_stream_read_window(info + SIZE_PAYLOAD_HEADER, len - SIZE_PAYLOAD_HEADER, &win)) {
        NABTO_LOG_DEBUG(("ReadWin failure"));
        return;
    }

    {
        text msg;
        switch (win.type) {
        case NP_PAYLOAD_WINDOW_FLAG_SYN                             : msg = "SYN";     break;
        case NP_PAYLOAD_WINDOW_FLAG_SYN | NP_PAYLOAD_WINDOW_FLAG_ACK: msg = "SYN|ACK"; break;
        case NP_PAYLOAD_WINDOW_FLAG_FIN | NP_PAYLOAD_WINDOW_FLAG_ACK: msg = "FIN|ACK"; break;
        case NP_PAYLOAD_WINDOW_FLAG_RST                             : msg = "RST";     break;
        case NP_PAYLOAD_WINDOW_FLAG_ACK                             : msg = "DATA";    break;
        default       : msg = "?"; NABTO_LOG_TRACE(("Type?: %" PRIu8, win.type)); break;

        }
        NABTO_NOT_USED(msg);
        NABTO_LOG_DEBUG(("%" PRIu16 " --> [%" PRIu32 ",%" PRIu32 "] %" PRItext ", %d bytes", hdr->tag, win.seq, win.ack, msg, dlen));
    }

    stream = find_stream(hdr->tag, con);
    if (stream == NULL) {
        if (win.type == NP_PAYLOAD_WINDOW_FLAG_SYN) {
            stream = find_free_stream(hdr->tag, con);
            if (stream == NULL) {
                NABTO_LOG_DEBUG(("Stream with tag %i not accepted", hdr->tag));
            }
        } else {
            NABTO_LOG_DEBUG(("Received non syn packet for stream which is not available tag %i", hdr->tag));
        }
    }

    if (stream == NULL) {
        if (! (win.type & NP_PAYLOAD_WINDOW_FLAG_RST)) {
            build_and_send_rst_packet(con, hdr->tag, &win);
        }
        return;
    }
    
    if (!nabto_stream_validate_win(&win, stream)) {
        NABTO_LOG_ERROR(("Cannot validate received stream window."));
        return;
    }

    NABTO_LOG_TRACE(("(.%i.) Stream with tag %i accepted, slot=%i", con->spnsi, hdr->tag, unabto_stream_index(stream)));

    stream->stats.receivedPackets++;
 
    memset(&sackData, 0, sizeof(sackData));
    {
        uint8_t* ptr = sackStart;
        while(sackLength >= 8 && sackData.nPairs < NP_PAYLOAD_SACK_MAX_PAIRS) {
            uint32_t sackSeqStart; // start of sack 
            uint32_t sackSeqEnd; // end of sack one larger than actual acked window.
            READ_FORWARD_U32(sackSeqStart, ptr);
            READ_FORWARD_U32(sackSeqEnd, ptr);
            sackLength -= 8;
            
            sackData.pairs[sackData.nPairs].start = sackSeqStart;
            sackData.pairs[sackData.nPairs].end = sackSeqEnd;
            sackData.nPairs++;
        }
    }

    nabto_stream_tcb_event(stream, &win, start, dlen, &sackData);
}