bool build_and_send_rst_packet(nabto_connect* con, uint16_t tag, struct nabto_win_info* win) { struct nabto_win_info rst; uint16_t winLength; uint16_t encodeLength; uint8_t* ptr; uint8_t* buf = nabtoCommunicationBuffer; memset(&rst, 0, sizeof( struct nabto_win_info)); nabto_stream_make_rst_response_window(win, &rst); winLength = nabto_stream_window_payload_length(&rst); ptr = insert_data_header(buf, con->spnsi, con->nsico, tag); ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_WINDOW, 0, winLength); if (nabto_stream_encode_window(&rst, ptr, &encodeLength)) { ptr += encodeLength; } else { return false; } ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_CRYPTO, 0, 0); return send_and_encrypt_packet_con(con, 0, 0, ptr); }
bool build_and_send_packet(struct nabto_stream_s* stream, uint8_t type, uint32_t seq, const uint8_t* winInfoData, size_t winInfoSize, uint8_t* data, uint16_t size, struct nabto_stream_sack_data* sackData) { enum { l_win = NP_PAYLOAD_WINDOW_SYN_BYTELENGTH - NP_PAYLOAD_WINDOW_BYTELENGTH }; uint8_t* ptr; nabto_connect* con = stream->connection; uint8_t* buf = nabtoCommunicationBuffer; struct nabto_stream_tcb* tcb = &stream->u.tcb; uint32_t ackToSend = unabto_stream_ack_number_to_send(tcb); uint16_t recvWinSize = unabto_stream_advertised_window_size(tcb); if (con == NULL) { return false; } nabtoSetFutureStamp(&tcb->ackStamp, 2*tcb->cfg.timeoutMsec); ptr = insert_data_header(buf, con->spnsi, con->nsico, stream->streamTag); ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_WINDOW, 0, l_win + winInfoSize + (type == NP_PAYLOAD_WINDOW_FLAG_ACK ? 2 : 0)); WRITE_FORWARD_U8 (ptr, type); WRITE_FORWARD_U8 (ptr, NP_STREAM_VERSION); WRITE_FORWARD_U16(ptr, stream->idCP); WRITE_FORWARD_U16(ptr, stream->idSP); WRITE_FORWARD_U32(ptr, seq); WRITE_FORWARD_U32(ptr, ackToSend); if (type == NP_PAYLOAD_WINDOW_FLAG_ACK) { WRITE_FORWARD_U16(ptr, recvWinSize); } if (winInfoSize) { memcpy(ptr, (const void*) winInfoData, winInfoSize); ptr += winInfoSize; } if (sackData && sackData->nPairs > 0) { uint8_t i; ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_SACK, 0, 8 * sackData->nPairs); for (i = 0; i < sackData->nPairs; i++) { WRITE_FORWARD_U32(ptr, sackData->pairs[i].start); WRITE_FORWARD_U32(ptr, sackData->pairs[i].end); } } ptr = insert_payload(ptr, NP_PAYLOAD_TYPE_CRYPTO, 0, 0); if (send_and_encrypt_packet_con(con, data, size, ptr)) { tcb->ackSent = ackToSend; tcb->lastSentAdvertisedWindow = recvWinSize; stream->stats.sentPackets++; return true; } else { return false; } }