/** * This code makes a connection unique, we have tried to make * connections through several channels. But when we receives the * first real data message on one channel we know that the client * ended up using this specific channel. */ void nabto_connection_end_connecting(nabto_connect* con, message_event* event) { if (event->type == MT_UDP) { #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_close(con); #endif con->state = CS_CONNECTED; con->type = NCT_REMOTE_P2P; con->conAttr = CON_ATTR_DEFAULT; con->socket = event->udpMessage.socket; NABTO_LOG_TRACE(("Received data on socket %i", con->socket)); con->peer = event->udpMessage.peer; if (EP_EQUAL(event->udpMessage.peer, nmc.context.gsp)) { NABTO_LOG_INFO((PRInsi " UDP Fallback through the GSP ", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); } else { NABTO_LOG_INFO((PRInsi " Direct UDP connection", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); } } #if NABTO_ENABLE_TCP_FALLBACK if (event->type == MT_TCP_FALLBACK) { con->state = CS_CONNECTED; con->type = NCT_REMOTE_RELAY_MICRO; con->conAttr |= con->fbConAttr; NABTO_LOG_INFO((PRInsi " TCP FAllback connection ", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); } #endif nabto_rendezvous_end(con); con->sendConnectStatistics = true; }
void nabto_release_connection(nabto_connect* con) { if (con->state != CS_IDLE) { NABTO_LOG_INFO((PRInsi " Release connection (record %i)", MAKE_NSI_PRINTABLE(0, con->spnsi, 0), nabto_connection_index(con))); if (con->state != CS_CLOSE_REQUESTED) { con->state = CS_CLOSE_REQUESTED; #if NABTO_ENABLE_STREAM nabto_stream_connection_released(con); #endif } if (con->socket != NABTO_INVALID_SOCKET) { if (con->socket != nmc.socketGSP && con->socket != nmc.socketLocal) { nabto_close_socket(&con->socket); } } // in case the rendezvous state is still active. nabto_rendezvous_end(con); #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_close(con); #endif con->state = CS_IDLE; nabto_crypto_release(&con->cryptoctx); } else { NABTO_LOG_TRACE(("nabto_release_connection called on non used connection")); } }
bool nabto_fallback_connect_u_event(uint16_t packetLength, nabto_packet_header* hdr) { nabto_connect* con; uint8_t* startOfPayloads; uint8_t* endOfPayloads; uint8_t* noncePayloadStart; uint16_t noncePayloadLength; uint8_t type; uint8_t flags; uint8_t* ptr; bool isReliable; bool hasKeepAlive; con = nabto_find_connection(hdr->nsi_sp); if (con == 0) { NABTO_LOG_TRACE((PRInsi " No connection found.", MAKE_NSI_PRINTABLE(hdr->nsi_cp, hdr->nsi_sp, 0))); return false; } startOfPayloads = nabtoCommunicationBuffer + hdr->hlen; endOfPayloads = nabtoCommunicationBuffer + packetLength; if (!find_payload(startOfPayloads, endOfPayloads, NP_PAYLOAD_TYPE_NONCE, &noncePayloadStart, &noncePayloadLength)) { NABTO_LOG_ERROR((PRI_tcp_fb "No nonce payload in GW_CONN_U packet.", TCP_FB_ARGS(con))); return false; } if (noncePayloadLength < 2) { NABTO_LOG_ERROR((PRI_tcp_fb "The payload received is too small to contain both flags and type.", TCP_FB_ARGS(con))); return false; } ptr = noncePayloadStart + NP_PAYLOAD_HDR_BYTELENGTH; READ_U8(type, ptr); ptr++; READ_U8(flags, ptr); ptr++; isReliable = (flags & NP_GW_CONN_U_FLAG_RELIABLE) != 0; hasKeepAlive = (flags & NP_GW_CONN_U_FLAG_KEEP_ALIVE) != 0; con->tcpFallbackConnectionState = UTFS_READY_FOR_DATA; // If the connection is still resolving upgrade it to a fallback connection. if (isReliable) { con->fbConAttr |= CON_ATTR_NO_RETRANSMIT; NABTO_LOG_DEBUG((PRI_tcp_fb "connection needs no retransmition", TCP_FB_ARGS(con))); } if (!hasKeepAlive) { con->fbConAttr |= CON_ATTR_NO_KEEP_ALIVE; NABTO_LOG_DEBUG((PRI_tcp_fb "connection needs no keep alive", TCP_FB_ARGS(con))); } else { NABTO_LOG_DEBUG((PRI_tcp_fb "connection needs keep alive", TCP_FB_ARGS(con))); } return true; }
/** initialise a connection */ static void nabto_reset_connection(nabto_connect* con) { nabto_stamp_t tmp = nabtoGetStamp(); NABTO_LOG_TRACE((PRInsi " Reset connection", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); memset(con, 0, offsetof(nabto_connect, cryptoctx)); con->stamp = tmp; con->socket = NABTO_INVALID_SOCKET; con->stats.connectionStart = tmp; #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_init(con); #endif nabto_crypto_reset(&con->cryptoctx); }
bool connect_event(message_event* event, nabto_packet_header* hdr) { nabto_endpoint* peer = &event->udpMessage.peer; bool isLocal = (event->udpMessage.socket == nmc.socketLocal); NABTO_LOG_TRACE(("U_CONNECT: Searching for hdr->nsi_cp=%" PRIu32 " (should not be found)", hdr->nsi_cp)); if (nabto_find_connection(hdr->nsi_cp) == NULL) { uint32_t nsi; uint32_t ec = 0; nabto_connect* con = nabto_init_connection(hdr, &nsi, &ec, isLocal); if (con) { size_t olen; NABTO_LOG_TRACE(("Couldn't find connection (good!). Created a new connection (nsi=%" PRIu32 ") con->spnsi=%" PRIu32, nsi, con->spnsi)); olen = mk_gsp_connect_rsp(nabtoCommunicationBuffer, hdr->seq, NOTIFY_CONNECT_OK, con->spnsi, hdr->nsi_cp, hdr->nsi_sp, isLocal); if (olen == 0) { NABTO_LOG_ERROR(("U_CONNECT out of resources in connect event.")); nabto_release_connection(con); // no resources available } else { if (EP_EQUAL(*peer, nmc.context.gsp)) { send_to_basestation(nabtoCommunicationBuffer, olen, peer); } else { nabto_write(event->udpMessage.socket, nabtoCommunicationBuffer, olen, peer->addr, peer->port); } con->state = CS_CONNECTING; if (!con->noRendezvous) { nabto_rendezvous_start(con); } #if NABTO_ENABLE_TCP_FALLBACK if (con->hasTcpFallbackCapabilities) { unabto_tcp_fallback_connect(con); } #endif return true; } } else if (nsi && ec) { // build negative answer size_t olen = mk_gsp_connect_rsp(nabtoCommunicationBuffer, hdr->seq, ec, nsi, hdr->nsi_cp, hdr->nsi_sp, isLocal); NABTO_LOG_TRACE((PRInsi " Deny connection, result: %" PRIu32, MAKE_NSI_PRINTABLE(0, nsi, 0), ec)); nabto_write(event->udpMessage.socket, nabtoCommunicationBuffer, olen, peer->addr, peer->port); return true; } else { NABTO_LOG_ERROR(("U_CONNECT was a malformed connect event.")); } } return false; }
void nabto_release_connection_req(nabto_connect* con) { NABTO_LOG_DEBUG((PRInsi " Release connection req", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); if (con->state != CS_CLOSE_REQUESTED) { uint32_t timeout = con->timeOut; if (timeout > MAX_TIMEOUT) { timeout = MAX_TIMEOUT; } con->state = CS_CLOSE_REQUESTED; nabtoSetFutureStamp(&con->stamp, timeout); #if NABTO_ENABLE_STREAM nabto_stream_connection_closed(con); #endif con->sendConnectionEndedStatistics = true; } else { NABTO_LOG_TRACE(("nabto_release_connection_req on closed connection")); } }
void nabto_release_connection_req(nabto_connect* con) { NABTO_LOG_DEBUG((PRInsi " Release connection req", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); if (con->state != CS_CLOSE_REQUESTED) { uint32_t timeout = con->timeOut; if (timeout > MAX_TIMEOUT) { timeout = MAX_TIMEOUT; } con->state = CS_CLOSE_REQUESTED; unabto_connection_set_future_stamp(&con->stamp, timeout); #if NABTO_ENABLE_STREAM nabto_stream_connection_closed(con); #endif con->sendConnectionEndedStatistics = true; // trigger recalculation of timeout such that statistics can be sent. connection_timeout_cache_cached = false; } else { NABTO_LOG_TRACE(("nabto_release_connection_req on closed connection")); } }
void nabto_time_event_connection(void) { nabto_connect* con; for (con = connections; con < connections + NABTO_CONNECTIONS_SIZE; ++con) { if (con->state != CS_IDLE) { rendezvous_time_event(con); statistics_time_event(con); #if NABTO_ENABLE_TCP_FALLBACK unabto_tcp_fallback_event(con); #endif if (nabto_connection_has_keep_alive(con) && nabtoIsStampPassed(&con->stamp)) { NABTO_LOG_DEBUG((PRInsi " Connection timeout", MAKE_NSI_PRINTABLE(0, con->spnsi, 0))); //, Stamp value is: %ul", con->spnsi, con->stamp)); nabto_release_connection(con); } } } #if NABTO_ENABLE_STREAM unabto_time_event_stream(); #endif }
static void send_rendezvous_socket(nabto_socket_t socket, nabto_connect* con, uint16_t seq, nabto_endpoint* dest, nabto_endpoint *myAddress) { uint8_t* ptr; uint8_t* buf = nabtoCommunicationBuffer; ptr = insert_header(buf, 0, con->spnsi, U_CONNECT, false, seq, 0, 0); ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_EP, 0, 6); WRITE_U32(ptr, dest->addr); ptr += 4; WRITE_U16(ptr, dest->port); ptr += 2; if (seq > 0) { if (!myAddress) { NABTO_LOG_ERROR(("Send rendezvous called with an invalid address")); return; } else { ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_EP, 0, 6); WRITE_U32(ptr, myAddress->addr); ptr += 4; WRITE_U16(ptr, myAddress->port); ptr += 2; } } { size_t len = ptr - buf; insert_length(buf, len); if (seq) { NABTO_LOG_DEBUG((PRInsi " RENDEZVOUS Send to " PRIep ": seq=%" PRIu16 " " PRIep, MAKE_NSI_PRINTABLE(0, con->spnsi, 0), MAKE_EP_PRINTABLE(*dest), seq, MAKE_EP_PRINTABLE(*myAddress))); } else { NABTO_LOG_DEBUG((PRInsi " RENDEZVOUS Send to " PRIep ": seq=0", MAKE_NSI_PRINTABLE(0, con->spnsi, 0), MAKE_EP_PRINTABLE(*dest))); } if (dest->addr != 0 && dest->port != 0) { nabto_write(socket, buf, len, dest->addr, dest->port); } else { NABTO_LOG_TRACE(("invalid rendezvous packet thrown away")); } } }
bool rendezvous_event(message_event* event, nabto_packet_header* hdr) { uint8_t* end = nabtoCommunicationBuffer + hdr->len; uint16_t res = hdr->hlen; uint8_t* ptr; uint8_t type; nabto_endpoint epUD; nabto_connect* con = 0; nabto_endpoint src; uint32_t interval = 5000; src = event->udpMessage.peer; NABTO_LOG_TRACE((PRInsi " Received from " PRIep " seq=%" PRIu16, MAKE_NSI_PRINTABLE(0, hdr->nsi_sp, 0), MAKE_EP_PRINTABLE(src), hdr->seq)); ptr = nabtoCommunicationBuffer + res; res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER; if (res != 6 || type != NP_PAYLOAD_TYPE_EP) { NABTO_LOG_TRACE(("Can't read first EP")); return false; } READ_U32(epUD.addr, ptr); ptr += 4; READ_U16(epUD.port, ptr); ptr += 2; res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER; if (res == 6 && type == NP_PAYLOAD_TYPE_EP) { // The second EP is not neccessary since we read the destination ep from the udp packet. ptr += 6; res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER; if (res == 4 && type == NP_PAYLOAD_TYPE_NONCE) { READ_U32(interval, ptr); NABTO_LOG_TRACE((PRInsi " Read interval from packet: %" PRIu32, MAKE_NSI_PRINTABLE(0, hdr->nsi_sp, 0), interval)); if (interval == 0) { NABTO_LOG_WARN(("Interval was 0, setting to 5000")); interval = 5000; } } } con = nabto_find_connection(hdr->nsi_sp); if (!con) { NABTO_LOG_ERROR(("Connection was not found, nsi: %i", hdr->nsi_sp)); } else { if (hdr->seq == 0) { send_rendezvous_socket(event->udpMessage.socket, con, 1, &src, &epUD); } else if (hdr->seq == 1) { send_rendezvous_socket(event->udpMessage.socket, con, 2, &src, &epUD); if (!conclude_connection(con, &src, interval)) { return false; } } else if (hdr->seq == 2) { if (!conclude_connection(con, &src, interval)) { return false; } } else { NABTO_LOG_ERROR(("Invalid Sequence Number")); } } return false; }
nabto_connect* nabto_init_connection(nabto_packet_header* hdr, uint32_t* nsi, uint32_t* ec, bool isLocal) { uint8_t type; uint8_t flags; /* NP_PAYLOAD_IPX_FLAG_* */ nabto_connect* con; const uint8_t* end = nabtoCommunicationBuffer + hdr->len; uint8_t* ptr = nabtoCommunicationBuffer + hdr->hlen; uint16_t res; uint16_t ipxPayloadLength; ipxPayloadLength = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER; *nsi = 0; *ec = 0; if ((ipxPayloadLength != IPX_PAYLOAD_LENGTH_WITHOUT_NSI) && (ipxPayloadLength != IPX_PAYLOAD_LENGTH_WITH_NSI) && (ipxPayloadLength != IPX_PAYLOAD_LENGTH_FULL_NSI)) { NABTO_LOG_TRACE(("Illegal payload size in U_CONNECT request from GSP: %" PRIu16 " %" PRIu8, ipxPayloadLength, type)); return 0; } if (type != NP_PAYLOAD_TYPE_IPX) { NABTO_LOG_TRACE(("Illegal payload type in U_CONNECT request from GSP: %" PRIu16 " %" PRIu8, ipxPayloadLength, type)); return 0; } if (ipxPayloadLength == IPX_PAYLOAD_LENGTH_WITH_NSI || ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) { READ_U32(*nsi, ptr + 13); NABTO_LOG_TRACE(("IPX payload with NSI (SPNSI=%" PRIu32 ")", *nsi)); } else { *nsi = fresh_nsi(); NABTO_LOG_TRACE(("IPX payload without NSI (fresh NSI=%" PRIu32 ")", *nsi)); } if (*nsi == 0) { NABTO_LOG_ERROR(("Trying to create connection with spnsi == 0")); return 0; } if (nabto_find_connection(*nsi)) { NABTO_LOG_DEBUG((PRInsi " A connection already exists this is probably a retransmission", MAKE_NSI_PRINTABLE(0, *nsi, 0))); *ec = NOTIFY_CONNECT_OK; return 0; } con = nabto_init_connection_real(*nsi); if (con == 0) { if (nabto_find_connection(*nsi)) { NABTO_LOG_DEBUG((PRInsi " U_CONNECT: A connection resource is already pending new connection", MAKE_NSI_PRINTABLE(0, *nsi, 0))); } else { NABTO_LOG_INFO((PRInsi " U_CONNECT: No connection resources free for new connection", MAKE_NSI_PRINTABLE(0, *nsi, 0))); #if NABTO_ENABLE_DEVICE_BUSY_AS_FATAL NABTO_LOG_FATAL((PRInsi " U_CONNECT: No free connections configured to be considered fatal", MAKE_NSI_PRINTABLE(0, *nsi, 0))); #endif } *ec = NOTIFY_ERROR_BUSY_MICRO; return 0; } NABTO_LOG_DEBUG((PRInsi " U_CONNECT: Connecting using record %i", MAKE_NSI_PRINTABLE(0, *nsi, 0), nabto_connection_index(con))); READ_U32(con->cp.privateEndpoint.addr, ptr + 0); READ_U16(con->cp.privateEndpoint.port, ptr + 4); READ_U32(con->cp.globalEndpoint.addr, ptr + 6); READ_U16(con->cp.globalEndpoint.port, ptr + 10); READ_U8(flags, ptr + 12); /* the final word (4 bytes) has been read already (nsi) */ con->noRendezvous = (flags & NP_PAYLOAD_IPX_FLAG_NO_RENDEZVOUS) ? 1 : 0; con->cpEqual = EP_EQUAL(con->cp.privateEndpoint, con->cp.globalEndpoint); con->cpAsync = (flags & NP_PAYLOAD_IPX_FLAG_CP_ASYNC) ? 1 : 0; con->clientNatType = (flags & NP_PAYLOAD_IPX_NAT_MASK); con->isLocal = isLocal; NABTO_LOG_INFO((PRInsi " U_CONNECT: cp.private: " PRIep " cp.global: " PRIep ", noRdv=%" PRIu8 ", cpeq=%" PRIu8 ", asy=%" PRIu8 ", NATType: %" PRIu8 , MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), MAKE_EP_PRINTABLE(con->cp.globalEndpoint), con->noRendezvous, con->cpEqual, con->cpAsync, con->clientNatType)); #if NABTO_ENABLE_TCP_FALLBACK if (ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) { memcpy(con->consi, ptr+17, 8); con->nsico = con->consi; READ_U32(con->cpnsi, ptr+25); } #endif ptr += ipxPayloadLength; //IPX_PAYLOAD_LENGTH_WITHOUT_NSI or IPX_PAYLOAD_LENGTH_WITH_NSI con->clientId[0] = 0; res = nabto_rd_payload(ptr, end, &type); if (type == NP_PAYLOAD_TYPE_CP_ID) { uint8_t idType; ptr += SIZE_PAYLOAD_HEADER; if (res > 0) { READ_U8(idType, ptr); ++ptr; --res; if (idType == 1) { // 1 == EMAIL size_t sz = res; if (sz >= sizeof(con->clientId)) { if (sizeof(con->clientId) > 1) { NABTO_LOG_WARN(("Client ID truncated")); } sz = sizeof(con->clientId) - 1; } if (sz) { memcpy(con->clientId, (const void*) ptr, sz); } con->clientId[sz] = 0; } } NABTO_LOG_TRACE(("Connection opened from '%s' (to %s)", con->clientId, nmc.nabtoMainSetup.id)); ptr += res; } #if NABTO_ENABLE_CONNECTION_ESTABLISHMENT_ACL_CHECK if (!allow_client_access(con)) { *ec = NOTIFY_ERROR_CP_ACCESS; goto init_error; } #endif #if NABTO_ENABLE_TCP_FALLBACK { uint8_t* gatewayPtr = ptr; res = nabto_rd_payload(ptr, end, &type); if (type == NP_PAYLOAD_TYPE_GW && ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) { uint8_t* gatewayEndPtr; size_t idLength; NABTO_LOG_TRACE(("The connect contains a gateway payload.")); ptr += res + SIZE_PAYLOAD_HEADER; gatewayPtr += SIZE_PAYLOAD_HEADER; gatewayEndPtr = ptr; READ_U32(con->fallbackHost.addr, gatewayPtr); gatewayPtr+=4; READ_U16(con->fallbackHost.port, gatewayPtr); gatewayPtr+=2; // skip the nsi gatewayPtr+=4; idLength = gatewayEndPtr-gatewayPtr; if (idLength != 20) { NABTO_LOG_FATAL(("The id length should be 20 bytes. bytes=%" PRIsize, idLength)); // todo } memcpy(con->gatewayId, gatewayPtr, 20); con->hasTcpFallbackCapabilities = true; } } #endif #if NABTO_ENABLE_UCRYPTO if (nmc.context.nonceSize == NONCE_SIZE) { uint8_t* decryptedDataStart; uint16_t decryptedDataLength; if (!unabto_connection_verify_and_decrypt_connect_packet(hdr, &decryptedDataStart, &decryptedDataLength)) { NABTO_LOG_TRACE(("Failed to read crypto payload in U_CONNECT")); } else { unabto_crypto_reinit_d(&con->cryptoctx, nmc.nabtoMainSetup.cryptoSuite, decryptedDataStart, decryptedDataLength); } } else #endif { NABTO_LOG_TRACE(("######## U_CONNECT without crypto payload")); unabto_crypto_reinit_d(&con->cryptoctx, CRYPT_W_NULL_DATA, 0, 0); } con->timeOut = CONNECTION_TIMEOUT; nabtoSetFutureStamp(&con->stamp, 20000); /* give much extra time during initialisation */ if (!verify_connection_encryption(con)) { goto init_crypto_error; } if (con->cpEqual) { NABTO_LOG_DEBUG((PRInsi " U_CONNECT: addr:" PRIep " rendezvous:%" PRIu8, MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), !con->noRendezvous)); } else { NABTO_LOG_DEBUG((PRInsi " U_CONNECT: private:" PRIep ", global:" PRIep " rendezvous:%" PRIu8, MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), MAKE_EP_PRINTABLE(con->cp.globalEndpoint), !con->noRendezvous)); } NABTO_LOG_INFO(("Connection opened from '%s' (to %s). Encryption code %i", con->clientId, nmc.nabtoMainSetup.id, con->cryptoctx.code)); return con; init_crypto_error: *ec = NOTIFY_ERROR_ENCR_MISMATCH; #if NABTO_ENABLE_CONNECTION_ESTABLISHMENT_ACL_CHECK init_error: nabto_release_connection(con); #endif return 0; }
/* Handle event by polling application - use data from header stored in data */ application_event_result framework_poll_event(struct naf_handle_s *handle, uint8_t *buf, uint16_t size, uint16_t *olen) { unabto_buffer w_buf; unabto_query_response w_b; uint16_t expected_len; uint8_t *ptr; uint32_t query_id; application_event_result res; uint16_t dlen; expected_len = handle->header.hlen + OFS_DATA; if (size <= expected_len) { NABTO_LOG_ERROR(("buffer too small to contain reconstructed header. size=%" PRIu16 " needed=%" PRIu16, size, expected_len)); return AER_REQ_SYSTEM_ERROR; } /* Write packet header and crypto payload header into buf. */ ptr = reconstruct_header(buf, &handle->header); if (!ptr) { //log message already given (header length mismatch) return AER_REQ_SYSTEM_ERROR; } { ptrdiff_t diff = ptr - buf; if (expected_len != (uint16_t)(diff)) { NABTO_LOG_ERROR(("header (with crypto) length mismatch: %" PRIu16 " != %" PRIptrdiff " !!!!!!!!!!!!!!!!!!!", expected_len, diff)); return AER_REQ_SYSTEM_ERROR; } } /* Set up a write buffer to write into buf (after crypto payload header). */ unabto_buffer_init(&w_buf, buf + expected_len, (int)(size - expected_len)); unabto_query_response_init(&w_b, &w_buf); /* Start reading input buffer from start again. */ unabto_query_request_reset(&handle->readBuffer); /* Skip query id. */ if (!unabto_query_read_uint32(&handle->readBuffer, &query_id)) { return AER_REQ_NO_QUERY_ID; } /* Call application */ NABTO_LOG_TRACE(("APPREQ application_poll: client=" PRI_client_id_q, CLIENT_ID_Q_ARGH(*handle))); res = application_poll(&handle->applicationRequest, NULL, &w_b); NABTO_LOG_TRACE(("APPREQ application_poll: result=%i %" PRItext, res, result_s(res))); if (res != AER_REQ_RESPONSE_READY) { return res; } dlen = unabto_crypto_max_data(&handle->connection->cryptoctx, (uint16_t)(size - expected_len)); if (!unabto_encrypt(&handle->connection->cryptoctx, ptr, unabto_query_response_used(&w_b), ptr, dlen, &dlen)) { NABTO_LOG_TRACE((PRInsi" Encryption failure", MAKE_NSI_PRINTABLE(0, handle->header.nsi_sp, 0))); return AER_REQ_SYSTEM_ERROR; } /* Update packet length and flag fields */ dlen += expected_len; insert_length(buf, dlen); if (!unabto_insert_integrity(&handle->connection->cryptoctx, buf, dlen)) { NABTO_LOG_TRACE((PRInsi" Signing failure", MAKE_NSI_PRINTABLE(0, handle->header.nsi_sp, 0))); return AER_REQ_SYSTEM_ERROR; } *olen = dlen; return AER_REQ_RESPONSE_READY; }