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