void unabto_tunnel_stream_accept(unabto_stream* stream) { tunnel* t = &tunnels[unabto_stream_index(stream)]; NABTO_LOG_TRACE(("Accepting stream and assigning it to tunnel %i", t)); UNABTO_ASSERT(t->state == TS_IDLE); unabto_tunnel_reset_tunnel_struct(t); t->stream = stream; t->state = TS_READ_COMMAND; t->tunnelId = tunnelCounter++; }
void unabto_stream_init_buffers(struct nabto_stream_s* stream) { int i; struct nabto_stream_tcb* tcb = &stream->u.tcb; uint8_t* xmitBase = x_buffer_data + (unabto_stream_index(stream) * NABTO_STREAM_SEND_SEGMENT_SIZE * NABTO_STREAM_SEND_WINDOW_SIZE); uint8_t* recvBase = r_buffer_data + (unabto_stream_index(stream) * NABTO_STREAM_RECEIVE_SEGMENT_SIZE * NABTO_STREAM_RECEIVE_WINDOW_SIZE); tcb->xmit = &x_buffers[unabto_stream_index(stream) * NABTO_STREAM_SEND_WINDOW_SIZE]; tcb->recv = &r_buffers[unabto_stream_index(stream) * NABTO_STREAM_RECEIVE_WINDOW_SIZE]; for (i=0;i< NABTO_STREAM_SEND_WINDOW_SIZE;i++) { memset(&tcb->xmit[i], 0, sizeof(x_buffer)); tcb->xmit[i].buf = xmitBase + (i * NABTO_STREAM_SEND_SEGMENT_SIZE); } for (i=0;i< NABTO_STREAM_RECEIVE_WINDOW_SIZE;i++) { memset(&tcb->recv[i], 0, sizeof(r_buffer)); tcb->recv[i].buf = recvBase + (i * NABTO_STREAM_RECEIVE_SEGMENT_SIZE); } }
tunnel* unabto_tunnel_get_tunnel(unabto_stream* stream) { tunnel* t; t = &tunnels[unabto_stream_index(stream)]; return t; }
void unabto_tunnel_idle(tunnel* tunnel, tunnel_event_source event_source) { NABTO_LOG_ERROR(("Tunnel(%i), Event on tunnel which should not be in IDLE state. source %i, unabtoReadState %i, stream index %i, Tunnel type unrecognized.", tunnel->tunnelId, event_source,tunnel->unabtoReadState, unabto_stream_index(tunnel->stream))); }
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); }
void nabto_stream_connection_released(nabto_connect* con) { struct nabto_stream_s* stream; for (stream = stream__; stream < stream__ + NABTO_MEMORY_STREAM_MAX_STREAMS; ++stream) { if (stream->connection == con && stream->state != STREAM_IDLE) { NABTO_LOG_TRACE(("Releasing stream, slot=%i, (connection closed) in state %" PRItext, unabto_stream_index(stream), nabto_stream_state_name(stream))); nabto_stream_tcb_on_connection_released(stream); stream->connection = NULL; } } }