Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/tcp/tcp.c

    rd14840d r2989c7e  
    3636
    3737#include <async.h>
     38#include <bitops.h>
     39#include <byteorder.h>
    3840#include <errno.h>
     41#include <inet/inet.h>
    3942#include <io/log.h>
    4043#include <stdio.h>
     44#include <stdlib.h>
    4145#include <task.h>
    4246
    4347#include "conn.h"
    44 #include "inet.h"
    4548#include "ncsim.h"
     49#include "pdu.h"
    4650#include "rqueue.h"
    4751#include "service.h"
     52#include "std.h"
     53#include "tcp.h"
    4854#include "test.h"
    49 #include "ucall.h"
    5055
    5156#define NAME       "tcp"
    5257
    53 static tcp_rqueue_cb_t tcp_rqueue_cb = {
    54         .seg_received = tcp_as_segment_arrived
     58static int tcp_inet_ev_recv(inet_dgram_t *dgram);
     59static void tcp_received_pdu(tcp_pdu_t *pdu);
     60
     61static inet_ev_ops_t tcp_inet_ev_ops = {
     62        .recv = tcp_inet_ev_recv
    5563};
     64
     65/** Received datagram callback */
     66static int tcp_inet_ev_recv(inet_dgram_t *dgram)
     67{
     68        uint8_t *pdu_raw;
     69        size_t pdu_raw_size;
     70
     71        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv()");
     72
     73        pdu_raw = dgram->data;
     74        pdu_raw_size = dgram->size;
     75
     76        /* Split into header and payload. */
     77
     78        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
     79
     80        tcp_pdu_t *pdu;
     81        size_t hdr_size;
     82        tcp_header_t *hdr;
     83        uint32_t data_offset;
     84
     85        if (pdu_raw_size < sizeof(tcp_header_t)) {
     86                log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
     87                    pdu_raw_size, sizeof(tcp_header_t));
     88                return EINVAL;
     89        }
     90
     91        hdr = (tcp_header_t *)pdu_raw;
     92        data_offset = BIT_RANGE_EXTRACT(uint32_t, DF_DATA_OFFSET_h, DF_DATA_OFFSET_l,
     93            uint16_t_be2host(hdr->doff_flags));
     94
     95        hdr_size = sizeof(uint32_t) * data_offset;
     96
     97        if (pdu_raw_size < hdr_size) {
     98                log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
     99                    pdu_raw_size, hdr_size);
     100                return EINVAL;
     101        }
     102
     103        if (hdr_size < sizeof(tcp_header_t)) {
     104                log_msg(LOG_DEFAULT, LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
     105                    hdr_size, sizeof(tcp_header_t));            return EINVAL;
     106        }
     107
     108        log_msg(LOG_DEFAULT, LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
     109            pdu_raw_size, hdr_size);
     110        pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size,
     111            pdu_raw_size - hdr_size);
     112        if (pdu == NULL) {
     113                log_msg(LOG_DEFAULT, LVL_WARN, "Failed creating PDU. Dropped.");
     114                return ENOMEM;
     115        }
     116
     117        pdu->src = dgram->src;
     118        pdu->dest = dgram->dest;
     119
     120        tcp_received_pdu(pdu);
     121        tcp_pdu_delete(pdu);
     122
     123        return EOK;
     124}
     125
     126/** Transmit PDU over network layer. */
     127void tcp_transmit_pdu(tcp_pdu_t *pdu)
     128{
     129        int rc;
     130        uint8_t *pdu_raw;
     131        size_t pdu_raw_size;
     132        inet_dgram_t dgram;
     133
     134        pdu_raw_size = pdu->header_size + pdu->text_size;
     135        pdu_raw = malloc(pdu_raw_size);
     136        if (pdu_raw == NULL) {
     137                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU. Out of memory.");
     138                return;
     139        }
     140
     141        memcpy(pdu_raw, pdu->header, pdu->header_size);
     142        memcpy(pdu_raw + pdu->header_size, pdu->text,
     143            pdu->text_size);
     144
     145        dgram.iplink = 0;
     146        dgram.src = pdu->src;
     147        dgram.dest = pdu->dest;
     148        dgram.tos = 0;
     149        dgram.data = pdu_raw;
     150        dgram.size = pdu_raw_size;
     151
     152        rc = inet_send(&dgram, INET_TTL_MAX, 0);
     153        if (rc != EOK)
     154                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
     155
     156        free(pdu_raw);
     157}
     158
     159/** Process received PDU. */
     160static void tcp_received_pdu(tcp_pdu_t *pdu)
     161{
     162        tcp_segment_t *dseg;
     163        inet_ep2_t rident;
     164
     165        log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
     166
     167        if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
     168                log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
     169                return;
     170        }
     171
     172        /* Insert decoded segment into rqueue */
     173        tcp_rqueue_insert_seg(&rident, dseg);
     174}
    56175
    57176static int tcp_init(void)
     
    68187        }
    69188
    70         tcp_rqueue_init(&tcp_rqueue_cb);
     189        tcp_rqueue_init();
    71190        tcp_rqueue_fibril_start();
    72191
     
    76195        if (0) tcp_test();
    77196
    78         rc = tcp_inet_init();
    79         if (rc != EOK)
     197        rc = inet_init(IP_PROTO_TCP, &tcp_inet_ev_ops);
     198        if (rc != EOK) {
     199                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
    80200                return ENOENT;
     201        }
    81202
    82203        rc = tcp_service_init();
Note: See TracChangeset for help on using the changeset viewer.