source: mainline/uspace/srv/net/tl/tcp/segment.c@ f343a16

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

FIN processing (WIP).

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[c5808b41]1/*
2 * Copyright (c) 2011 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/**
[032bbe7]34 * @file Segment processing
[c5808b41]35 */
36
[0093ab6]37#include <mem.h>
[c5808b41]38#include <stdlib.h>
39#include "segment.h"
40#include "seq_no.h"
41#include "tcp_type.h"
42
[032bbe7]43/** Alocate new segment structure. */
[c5808b41]44tcp_segment_t *tcp_segment_new(void)
45{
46 return calloc(1, sizeof(tcp_segment_t));
47}
48
[032bbe7]49/** Delete segment. */
[4c55a64]50void tcp_segment_delete(tcp_segment_t *seg)
51{
52 free(seg);
53}
54
[32105348]55/** Create a control-only segment.
[032bbe7]56 *
[32105348]57 * @return Segment
[032bbe7]58 */
[c5808b41]59tcp_segment_t *tcp_segment_make_ctrl(tcp_control_t ctrl)
60{
61 tcp_segment_t *seg;
62
63 seg = tcp_segment_new();
64 if (seg == NULL)
65 return NULL;
66
67 seg->ctrl = ctrl;
68 seg->len = seq_no_control_len(ctrl);
69
70 return seg;
71}
72
[032bbe7]73/** Create an RST segment.
74 *
75 * @param seg Segment we are replying to
76 * @return RST segment
77 */
[c5808b41]78tcp_segment_t *tcp_segment_make_rst(tcp_segment_t *seg)
79{
80 tcp_segment_t *rseg;
81
82 rseg = tcp_segment_new();
83 if (rseg == NULL)
84 return NULL;
85
86 rseg->ctrl = CTL_RST;
87 rseg->seq = seg->ack;
88
89 return rseg;
90}
91
[32105348]92/** Create a control segment.
93 *
94 * @return Segment
95 */
96tcp_segment_t *tcp_segment_make_data(tcp_control_t ctrl, void *data,
97 size_t size)
98{
99 tcp_segment_t *seg;
100
[8c7a054]101 assert(ctrl != 0 || size > 0);
[32105348]102
103 seg = tcp_segment_new();
104 if (seg == NULL)
105 return NULL;
106
107 seg->ctrl = ctrl;
108 seg->len = seq_no_control_len(ctrl) + size;
109
110 seg->dfptr = seg->data = malloc(size);
111 if (seg->dfptr == NULL) {
112 free(seg);
113 return NULL;
114 }
115
116 memcpy(seg->data, data, size);
117
118 return seg;
119}
120
121
[032bbe7]122/** Trim segment from left and right by the specified amount.
[0093ab6]123 *
[032bbe7]124 * Trim any text or control to remove the specified amount of sequence
125 * numbers from the left (lower sequence numbers) and right side
126 * (higher sequence numbers) of the segment.
127 *
128 * @param seg Segment, will be modified in place
129 * @param left Amount of sequence numbers to trim from the left
130 * @param right Amount of sequence numbers to trim from the right
[0093ab6]131 */
132void tcp_segment_trim(tcp_segment_t *seg, uint32_t left, uint32_t right)
133{
134 uint32_t t_size;
135
136 assert(left + right <= seg->len);
137
138 /* Special case, entire segment trimmed from left */
139 if (left == seg->len) {
140 seg->seq = seg->seq + seg->len;
141 seg->len = 0;
142 return;
143 }
144
145 /* Special case, entire segment trimmed from right */
146 if (right == seg->len) {
147 seg->len = 0;
148 return;
149 }
150
151 /* General case */
152
153 t_size = tcp_segment_text_size(seg);
154
155 if (left > 0 && (seg->ctrl & CTL_SYN) != 0) {
156 /* Trim SYN */
157 seg->ctrl &= ~CTL_SYN;
158 seg->seq++;
159 seg->len--;
160 left--;
161 }
162
163 if (right > 0 && (seg->ctrl & CTL_FIN) != 0) {
164 /* Trim FIN */
165 seg->ctrl &= ~CTL_FIN;
166 seg->len--;
167 right--;
168 }
169
170 if (left > 0 || right > 0) {
171 /* Trim segment text */
172 assert(left + right <= t_size);
173
174 seg->data += left;
175 seg->len -= left + right;
176 }
177}
178
179/** Copy out text data from segment.
180 *
[032bbe7]181 * Data is copied from the beginning of the segment text up to @a size bytes.
182 * @a size must not be greater than the size of the segment text, but
183 * it can be less.
184 *
185 * @param seg Segment
186 * @param buf Destination buffer
187 * @param size Size of destination buffer
[0093ab6]188 */
189void tcp_segment_text_copy(tcp_segment_t *seg, void *buf, size_t size)
190{
191 assert(size <= tcp_segment_text_size(seg));
192 memcpy(buf, seg->data, size);
193}
194
[032bbe7]195/** Return number of bytes in segment text.
196 *
197 * @param seg Segment
198 * @return Number of bytes in segment text
199 */
[0093ab6]200size_t tcp_segment_text_size(tcp_segment_t *seg)
[c5808b41]201{
202 return seg->len - seq_no_control_len(seg->ctrl);
203}
204
205/**
206 * @}
207 */
Note: See TracBrowser for help on using the repository browser.