Exemple #1
0
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;
    }
}