Bladeren bron

Removed to make way for the uIP-based tcp.c.

tags/v0.9.3
Michael Brown 18 jaren geleden
bovenliggende
commit
531371efa2
1 gewijzigde bestanden met toevoegingen van 0 en 286 verwijderingen
  1. 0
    286
      src/proto/tcp.c

+ 0
- 286
src/proto/tcp.c Bestand weergeven

@@ -1,286 +0,0 @@
1
-#include "etherboot.h"
2
-#include "ip.h"
3
-#include "tcp.h"
4
-#include "nic.h"
5
-
6
-void build_tcp_hdr(unsigned long destip, unsigned int srcsock,
7
-		  unsigned int destsock, long send_seq, long recv_seq,
8
-		  int window, int flags, int ttl, int len, const void *buf)
9
-{
10
-       struct iphdr *ip;
11
-       struct tcphdr *tcp;
12
-       ip = (struct iphdr *)buf;
13
-       build_ip_hdr(destip, ttl, IP_TCP, 0, len, buf);
14
-       tcp = (struct tcphdr *)(ip + 1);
15
-       tcp->src = htons(srcsock);
16
-       tcp->dst = htons(destsock);
17
-       tcp->seq = htonl(send_seq);
18
-       tcp->ack = htonl(recv_seq);
19
-       tcp->ctrl = htons(flags + (5 << 12)); /* No TCP options */
20
-       tcp->window = htons(window);
21
-       tcp->chksum = 0;
22
-       if ((tcp->chksum = tcpudpchksum(ip)) == 0)
23
-	       tcp->chksum = 0xffff;
24
-}
25
-
26
-/**************************************************************************
27
-TCP_TRANSMIT - Send a TCP packet
28
-**************************************************************************/
29
-int tcp_transmit(unsigned long destip, unsigned int srcsock,
30
-		unsigned int destsock, long send_seq, long recv_seq,
31
-		int window, int flags, int len, const void *buf)
32
-{
33
-       build_tcp_hdr(destip, srcsock, destsock, send_seq, recv_seq,
34
-		     window, flags, 60, len, buf);
35
-       return ip_transmit(len, buf);
36
-}
37
-
38
-int tcp_reset(struct iphdr *ip) {
39
-       struct tcphdr *tcp = (struct tcphdr *)(ip + 1);
40
-       char buf[sizeof(struct iphdr) + sizeof(struct tcphdr)];
41
-
42
-       if (!(tcp->ctrl & htons(RST))) {
43
-	      long seq = ntohl(tcp->seq) + ntohs(ip->len) -
44
-			 sizeof(struct iphdr) -
45
-			 ((ntohs(tcp->ctrl) >> 10) & 0x3C);
46
-	      if (tcp->ctrl & htons(SYN|FIN))
47
-		      seq++;
48
-	      return tcp_transmit(ntohl(ip->src.s_addr),
49
-				  ntohs(tcp->dst), ntohs(tcp->src),
50
-				  tcp->ctrl&htons(ACK) ? ntohl(tcp->ack) : 0,
51
-				  seq, TCP_MAX_WINDOW, RST, sizeof(buf), buf);
52
-       }
53
-       return (1);
54
-}
55
-
56
-/**************************************************************************
57
-TCP - Simple-minded TCP stack. Can only send data once and then
58
-      receive the response. The algorithm for computing window
59
-      sizes and delaying ack's is currently broken, and thus
60
-      disabled. Performance would probably improve a little, if
61
-      this gets fixed. FIXME
62
-**************************************************************************/
63
-static int await_tcp(int ival, void *ptr, unsigned short ptype __unused,
64
-		    struct iphdr *ip, struct udphdr *udp __unused,
65
-		    struct tcphdr *tcp)
66
-{
67
-       if (!tcp) {
68
-	       return 0;
69
-       }
70
-       if (arptable[ARP_CLIENT].ipaddr.s_addr != ip->dest.s_addr)
71
-	       return 0;
72
-       if (ntohs(tcp->dst) != ival) {
73
-	       tcp_reset(ip);
74
-	       return 0;
75
-       }
76
-       *(void **)ptr = tcp;
77
-       return 1;
78
-}
79
-
80
-int tcp_transaction(unsigned long destip, unsigned int destsock, void *ptr,
81
-		   int (*send)(int len, void *buf, void *ptr),
82
-		   int (*recv)(int len, const void *buf, void *ptr)) {
83
-       static uint16_t srcsock = 0;
84
-       int	       rc = 1;
85
-       long	       send_seq = currticks();
86
-       long	       recv_seq = 0;
87
-       int	       can_send = 0;
88
-       int	       sent_all = 0;
89
-       struct iphdr   *ip;
90
-       struct tcphdr  *tcp;
91
-       int	       ctrl = SYN;
92
-       char	       buf[128]; /* Small outgoing buffer */
93
-       long	       payload;
94
-       int	       header_size;
95
-       int	       window = 3*TCP_MIN_WINDOW;
96
-       long	       last_ack = 0;
97
-       long	       last_sent = 0;
98
-       long	       rtt = 0;
99
-       long	       srtt = 0;
100
-       long	       rto = TCP_INITIAL_TIMEOUT;
101
-       int	       retry = TCP_MAX_TIMEOUT/TCP_INITIAL_TIMEOUT;
102
-       enum { CLOSED, SYN_RCVD, ESTABLISHED,
103
-	      FIN_WAIT_1, FIN_WAIT_2 } state = CLOSED;
104
-
105
-       if (!srcsock) {
106
-	       srcsock = currticks();
107
-       }
108
-       if (++srcsock < 1024)
109
-	       srcsock += 1024;
110
-
111
-       rx_qdrain();
112
-
113
- send_data:
114
-       if (ctrl & ACK)
115
-	       last_ack = recv_seq;
116
-       if (!tcp_transmit(destip, srcsock, destsock, send_seq,
117
-			 recv_seq, window, ctrl,
118
-			 sizeof(struct iphdr) + sizeof(struct tcphdr)+
119
-			 can_send, buf)) {
120
-	       return (0);
121
-       }
122
-       last_sent = currticks();
123
-
124
- recv_data:
125
-       if (!await_reply(await_tcp, srcsock, &tcp,
126
-			(state == ESTABLISHED && !can_send)
127
-			? TCP_MAX_TIMEOUT : rto)) {
128
-	       if (state == ESTABLISHED) {
129
- close:
130
-		       ctrl = FIN|ACK;
131
-		       state = FIN_WAIT_1;
132
-		       rc = 0;
133
-		       goto send_data;
134
-	       }
135
-
136
-	       if (state == FIN_WAIT_1 || state == FIN_WAIT_2)
137
-		       return (rc);
138
-
139
-	       if (--retry <= 0) {
140
-		       /* time out */
141
-		       if (state == SYN_RCVD) {
142
-			       tcp_transmit(destip, srcsock, destsock,
143
-					    send_seq, 0, window, RST,
144
-					    sizeof(struct iphdr) +
145
-					    sizeof(struct tcphdr), buf);
146
-		       }
147
-		       return (0);
148
-	       }
149
-	       /* retransmit */
150
-	       goto send_data;
151
-       }
152
-       /* got_data: */
153
-       retry = TCP_MAX_RETRY;
154
-
155
-       if (tcp->ctrl & htons(ACK) ) {
156
-	       char *data;
157
-	       int syn_ack, consumed;
158
-
159
-	       if (state == FIN_WAIT_1 || state == FIN_WAIT_2) {
160
-		       state = FIN_WAIT_2;
161
-		       ctrl = ACK;
162
-		       goto consume_data;
163
-	       }
164
-	       syn_ack = state == CLOSED || state == SYN_RCVD;
165
-	       consumed = ntohl(tcp->ack) - send_seq - syn_ack;
166
-	       if (consumed < 0 || consumed > can_send) {
167
-		       tcp_reset((struct iphdr *)&nic.packet[ETH_HLEN]);
168
-		       goto recv_data;
169
-	       }
170
-
171
-	       rtt = currticks() - last_sent;
172
-	       srtt = !srtt ? rtt : (srtt*4 + rtt)/5;
173
-	       rto = srtt + srtt/2;
174
-	       if (rto < TCP_MIN_TIMEOUT)
175
-		       rto = TCP_MIN_TIMEOUT;
176
-	       else if (rto > TCP_MAX_TIMEOUT)
177
-		       rto = TCP_MAX_TIMEOUT;
178
-
179
-	       can_send -= consumed;
180
-	       send_seq += consumed + syn_ack;
181
-	       data = buf + sizeof(struct iphdr) + sizeof(struct tcphdr);
182
-	       if (can_send) {
183
-		       memmove(data, data + consumed, can_send);
184
-	       }
185
-	       if (!sent_all) {
186
-		       int more_data;
187
-		       data += can_send;
188
-		       more_data = buf + sizeof(buf) - data;
189
-		       if (more_data > 0) {
190
-			       more_data = send(more_data, data, ptr);
191
-			       can_send += more_data;
192
-		       }
193
-		       sent_all = !more_data;
194
-	       }
195
-	       if (state == SYN_RCVD) {
196
-		       state = ESTABLISHED;
197
-		       ctrl = PSH|ACK;
198
-		       goto consume_data;
199
-	       }
200
-	       if (tcp->ctrl & htons(RST))
201
-		       return (0);
202
-       } else if (tcp->ctrl & htons(RST)) {
203
-	       if (state == CLOSED)
204
-		       goto recv_data;
205
-	       return (0);
206
-       }
207
-
208
- consume_data:
209
-       ip  = (struct iphdr *)&nic.packet[ETH_HLEN];
210
-       header_size = sizeof(struct iphdr) + ((ntohs(tcp->ctrl)>>10)&0x3C);
211
-       payload = ntohs(ip->len) - header_size;
212
-       if (payload > 0 && state == ESTABLISHED) {
213
-	       int old_bytes = recv_seq - (long)ntohl(tcp->seq);
214
-	       if (old_bytes >= 0 && payload - old_bytes > 0) {
215
-		       recv_seq += payload - old_bytes;
216
-		       if (state != FIN_WAIT_1 && state != FIN_WAIT_2 &&
217
-			   !recv(payload - old_bytes,
218
-				 &nic.packet[ETH_HLEN+header_size+old_bytes],
219
-				 ptr)) {
220
-			       goto close;
221
-		       }
222
-		       if ((state == ESTABLISHED || state == SYN_RCVD) &&
223
-			   !(tcp->ctrl & htons(FIN))) {
224
-			       int in_window = window - 2*TCP_MIN_WINDOW >
225
-						recv_seq - last_ack;
226
-			       ctrl = can_send ? PSH|ACK : ACK;
227
-			       if (!can_send && in_window) {
228
-/* Window scaling is broken right now, just fall back to acknowledging every */
229
-/* packet immediately and unconditionally. FIXME		       */ /***/
230
-/*				       if (await_reply(await_tcp, srcsock,
231
-						       &tcp, rto))
232
-					       goto got_data;
233
-				       else */
234
-					       goto send_data;
235
-			       }
236
-			       if (!in_window) {
237
-				       window += TCP_MIN_WINDOW;
238
-				       if (window > TCP_MAX_WINDOW)
239
-					       window = TCP_MAX_WINDOW;
240
-			       }
241
-			       goto send_data;
242
-		       }
243
-	       } else {
244
-		       /* saw old data again, must have lost packets */
245
-		       window /= 2;
246
-		       if (window < 2*TCP_MIN_WINDOW)
247
-			       window = 2*TCP_MIN_WINDOW;
248
-	       }
249
-       }
250
-
251
-       if (tcp->ctrl & htons(FIN)) {
252
-	       if (state == ESTABLISHED) {
253
-		       ctrl = FIN|ACK;
254
-	       } else if (state == FIN_WAIT_1 || state == FIN_WAIT_2) {
255
-		       ctrl = ACK;
256
-	       } else {
257
-		       ctrl = RST;
258
-	       }
259
-	       return (tcp_transmit(destip, srcsock, destsock,
260
-				    send_seq, recv_seq + 1, window, ctrl,
261
-				    sizeof(struct iphdr) +
262
-				    sizeof(struct tcphdr), buf) &&
263
-		       (state == ESTABLISHED ||
264
-			state == FIN_WAIT_1 || state == FIN_WAIT_2) &&
265
-		       !can_send);
266
-       }
267
-
268
-       if (state == CLOSED) {
269
-	       if (tcp->ctrl & htons(SYN)) {
270
-		       recv_seq = ntohl(tcp->seq) + 1;
271
-		       if (!(tcp->ctrl & htons(ACK))) {
272
-			       state = SYN_RCVD;
273
-			       ctrl = SYN|ACK|PSH;
274
-			       goto send_data;
275
-		       } else {
276
-			       state = ESTABLISHED;
277
-			       ctrl = PSH|ACK;
278
-		       }
279
-	       }
280
-       }
281
-
282
-       if (can_send || payload) {
283
-	       goto send_data;
284
-       }
285
-       goto recv_data;
286
-}

Laden…
Annuleren
Opslaan