source: mainline/uspace/srv/net/tcp/inet.c@ 3cf22f9

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3cf22f9 was 3bacee1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Make ccheck-fix again and commit more good files.

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2015 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup tcp
30 * @{
31 */
32
33/**
34 * @file TCP inet interfacing
35 */
36
37#include <bitops.h>
38#include <byteorder.h>
39#include <errno.h>
40#include <inet/inet.h>
41#include <mem.h>
42#include <io/log.h>
43#include <stdlib.h>
44
45#include "inet.h"
46#include "pdu.h"
47#include "rqueue.h"
48#include "std.h"
49
50#define NAME "tcp"
51
52static errno_t tcp_inet_ev_recv(inet_dgram_t *dgram);
53static void tcp_received_pdu(tcp_pdu_t *pdu);
54
55static inet_ev_ops_t tcp_inet_ev_ops = {
56 .recv = tcp_inet_ev_recv
57};
58
59/** Received datagram callback */
60static errno_t tcp_inet_ev_recv(inet_dgram_t *dgram)
61{
62 uint8_t *pdu_raw;
63 size_t pdu_raw_size;
64
65 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv()");
66
67 pdu_raw = dgram->data;
68 pdu_raw_size = dgram->size;
69
70 /* Split into header and payload. */
71
72 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_ev_recv() - split header/payload");
73
74 tcp_pdu_t *pdu;
75 size_t hdr_size;
76 tcp_header_t *hdr;
77 uint32_t data_offset;
78
79 if (pdu_raw_size < sizeof(tcp_header_t)) {
80 log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < sizeof(tcp_header_t) = %zu",
81 pdu_raw_size, sizeof(tcp_header_t));
82 return EINVAL;
83 }
84
85 hdr = (tcp_header_t *)pdu_raw;
86 data_offset = BIT_RANGE_EXTRACT(uint32_t, DF_DATA_OFFSET_h, DF_DATA_OFFSET_l,
87 uint16_t_be2host(hdr->doff_flags));
88
89 hdr_size = sizeof(uint32_t) * data_offset;
90
91 if (pdu_raw_size < hdr_size) {
92 log_msg(LOG_DEFAULT, LVL_WARN, "pdu_raw_size = %zu < hdr_size = %zu",
93 pdu_raw_size, hdr_size);
94 return EINVAL;
95 }
96
97 if (hdr_size < sizeof(tcp_header_t)) {
98 log_msg(LOG_DEFAULT, LVL_WARN, "hdr_size = %zu < sizeof(tcp_header_t) = %zu",
99 hdr_size, sizeof(tcp_header_t));
100 return EINVAL;
101 }
102
103 log_msg(LOG_DEFAULT, LVL_DEBUG, "pdu_raw_size=%zu, hdr_size=%zu",
104 pdu_raw_size, hdr_size);
105 pdu = tcp_pdu_create(pdu_raw, hdr_size, pdu_raw + hdr_size,
106 pdu_raw_size - hdr_size);
107 if (pdu == NULL) {
108 log_msg(LOG_DEFAULT, LVL_WARN, "Failed creating PDU. Dropped.");
109 return ENOMEM;
110 }
111
112 pdu->src = dgram->src;
113 pdu->dest = dgram->dest;
114
115 tcp_received_pdu(pdu);
116 tcp_pdu_delete(pdu);
117
118 return EOK;
119}
120
121/** Transmit PDU over network layer. */
122void tcp_transmit_pdu(tcp_pdu_t *pdu)
123{
124 errno_t rc;
125 uint8_t *pdu_raw;
126 size_t pdu_raw_size;
127 inet_dgram_t dgram;
128
129 pdu_raw_size = pdu->header_size + pdu->text_size;
130 pdu_raw = malloc(pdu_raw_size);
131 if (pdu_raw == NULL) {
132 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU. Out of memory.");
133 return;
134 }
135
136 memcpy(pdu_raw, pdu->header, pdu->header_size);
137 memcpy(pdu_raw + pdu->header_size, pdu->text,
138 pdu->text_size);
139
140 dgram.iplink = 0;
141 dgram.src = pdu->src;
142 dgram.dest = pdu->dest;
143 dgram.tos = 0;
144 dgram.data = pdu_raw;
145 dgram.size = pdu_raw_size;
146
147 rc = inet_send(&dgram, INET_TTL_MAX, 0);
148 if (rc != EOK)
149 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed to transmit PDU.");
150
151 free(pdu_raw);
152}
153
154/** Process received PDU. */
155static void tcp_received_pdu(tcp_pdu_t *pdu)
156{
157 tcp_segment_t *dseg;
158 inet_ep2_t rident;
159
160 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_received_pdu()");
161
162 if (tcp_pdu_decode(pdu, &rident, &dseg) != EOK) {
163 log_msg(LOG_DEFAULT, LVL_WARN, "Not enough memory. PDU dropped.");
164 return;
165 }
166
167 /* Insert decoded segment into rqueue */
168 tcp_rqueue_insert_seg(&rident, dseg);
169}
170
171/** Initialize TCP inet interface. */
172errno_t tcp_inet_init(void)
173{
174 errno_t rc;
175
176 log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_inet_init()");
177
178 rc = inet_init(IP_PROTO_TCP, &tcp_inet_ev_ops);
179 if (rc != EOK) {
180 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed connecting to internet service.");
181 return ENOENT;
182 }
183
184 return EOK;
185}
186
187/**
188 * @}
189 */
Note: See TracBrowser for help on using the repository browser.