📄 tcp.lst
字号:
207 7 // Send reset and close connection
208 7 tcp_send(FLG_RST, 20, nr);
209 7 conxn[nr].ipaddr = 0;
210 7 }
211 6 }
212 5 }
213 4 }
214 3 }
215 2 }
216 1 }
217
218
219
220
221 //------------------------------------------------------------------------
222 // This runs every 0.5 seconds. If the connection has had no activity
223 // it initiates closing the connection.
224 //
225 //------------------------------------------------------------------------
226 void tcp_inactivity(void)
227 {
228 1 UCHAR idata nr;
229 1
230 1 // Look for active connections in the established state
231 1 for (nr = 0; nr < 5; nr++)
232 1 {
233 2 if ((conxn[nr].ipaddr != 0) &&
234 2 (conxn[nr].state == STATE_ESTABLISHED) &&
235 2 (conxn[nr].inactivity))
236 2 {
237 3 // Decrement the timer and see if it hit 0
238 3 conxn[nr].inactivity--;
239 3 if (conxn[nr].inactivity == 0)
240 3 {
241 4 // Inactivity timer has just timed out.
C51 COMPILER V7.06 TCP 10/09/2006 21:51:55 PAGE 5
242 4 // Initiate close of connection
243 4 tcp_send((FLG_ACK | FLG_FIN), 20, nr);
244 4 conxn[nr].my_sequence++; // For my FIN
245 4 conxn[nr].state = STATE_FIN_WAIT_1;
246 4
247 4 }
248 3 }
249 2 }
250 1 }
251
252
253
254 //------------------------------------------------------------------------
255 // This handles incoming TCP messages and manages the TCP state machine
256 // Note - both the SYN and FIN flags consume a sequence number.
257 // See "TCP/IP Illustrated, Volume 1" Sect 18.6 for info on TCP states
258 // See "TCP/IP Illustrated, Volume 1" Sect 17.3 for info on flags
259 //------------------------------------------------------------------------
260 void tcp_rcve(UCHAR xdata * inbuf, UINT len)
261 {
262 1 UCHAR idata i, j, nr;
263 1 UINT idata result, header_len, data_len;
264 1 TCP_HEADER xdata * tcp;
265 1 IP_HEADER xdata * ip;
266 1 ULONG idata sum;
267 1
268 1 // IP header is always 20 bytes so message starts at index 34
269 1 tcp = (TCP_HEADER xdata *)(inbuf + 34);
270 1 ip = (IP_HEADER xdata *)(inbuf + 14);
271 1
272 1 // Compute TCP checksum including 12 byte pseudoheader
273 1 // Sum source_ipaddr, dest_ipaddr, and entire TCP message
274 1 sum = (ULONG)cksum(inbuf + 26, 8 + len);
275 1
276 1 // Add in the rest of pseudoheader which is
277 1 // protocol id and TCP segment length
278 1 sum += (ULONG)0x0006;
279 1 sum += (ULONG)len;
280 1
281 1 // In case there was a carry, add it back around
282 1 result = (UINT)(sum + (sum >> 16));
283 1
284 1 if (result != 0xFFFF)
285 1 {
286 2 return;
287 2 }
288 1
289 1
290 1 // See if message is for http server
291 1 if (tcp->dest_port != HTTP_PORT)
292 1 {
293 2
294 2 tcp_send(FLG_RST, 20, NO_CONNECTION);
295 2 return;
296 2 }
297 1
298 1 // Capture sender's IP address and port number
299 1 sender_ipaddr = ip->source_ipaddr;
300 1 sender_tcpport = tcp->source_port;
301 1
302 1 // See if the TCP segment is from someone we are already
303 1 // connected to.
C51 COMPILER V7.06 TCP 10/09/2006 21:51:55 PAGE 6
304 1 for (i=0; i < 5; i++)
305 1 {
306 2 if ((ip->source_ipaddr == conxn[i].ipaddr) &&
307 2 (tcp->source_port == conxn[i].port))
308 2 {
309 3 nr = i;
310 3 break;
311 3 }
312 2 }
313 1
314 1 // If i = 5, we are not connected. If it is a SYN then assign
315 1 // a temporary conection to it for processing
316 1 if (i == 5)
317 1 {
318 2 if (tcp->flags & FLG_SYN)
319 2 {
320 3 // Find first unused connection (one with IP = 0)
321 3 for (j=0; j < 5; j++)
322 3 {
323 4 if (conxn[j].ipaddr == 0)
324 4 {
325 5 nr = j;
326 5 // Initialize new connection
327 5 conxn[nr].state = STATE_LISTEN;
328 5 break;
329 5 }
330 4 }
331 3
332 3 // If all connections are used then drop msg
333 3 if (j == 5) return;
334 3
335 3
336 3 }
337 2 }
338 1
339 1
340 1 // By now we should have a connection number in range of 0-4
341 1 // Do a check to avoid any chance of exceeding size of struct
342 1 if (nr > 4)
343 1 {
344 2 return;
345 2 }
346 1
347 1 // Eventually put in protection against wrapping sequence
348 1 // numbers, for now make the client start over if his
349 1 // sequence number is close to wrapping
350 1 if (tcp->sequence > 0xFFFFFF00L)
351 1 {
352 2
353 2 conxn[nr].ipaddr = 0;
354 2 tcp_send(FLG_RST, 20, NO_CONNECTION);
355 2 return;
356 2 }
357 1
358 1 // Handle messages whose action is mostly independent of state
359 1 // such as RST, SYN, and segment with no ACK. That way the
360 1 // state machine below does not need to worry about it.
361 1 if (tcp->flags & FLG_RST)
362 1 {
363 2 // An RST does not depend on state at all. And it does
364 2 // not count as data so do not send an ACK here. Close
365 2 // connection
C51 COMPILER V7.06 TCP 10/09/2006 21:51:55 PAGE 7
366 2 conxn[nr].ipaddr = 0;
367 2 return;
368 2 }
369 1
370 1 else if (tcp->flags & FLG_SYN)
371 1 {
372 2 // A SYN segment only makes sense if connection is in LISTEN
373 2 if ((conxn[nr].state != STATE_LISTEN) &&
374 2 (conxn[nr].state != STATE_CLOSED))
375 2 {
376 3 conxn[nr].ipaddr = 0;
377 3 tcp_send(FLG_RST, 20, NO_CONNECTION);
378 3 return;
379 3 }
380 2 }
381 1
382 1 else if ((tcp->flags & FLG_ACK) == 0)
383 1 {
384 2 // Incoming segments except SYN or RST must have ACK bit set
385 2 // See TCP/IP Illustrated, Vol 2, Page 965
386 2 // Drop segment but do not send a reset
387 2 return;
388 2 }
389 1
390 1 // Compute length of header including options, and from that
391 1 // compute length of actual data
392 1 header_len = (tcp->flags & 0xF000) >> 10;
393 1 data_len = len - header_len;
394 1
395 1
396 1
397 1 // Handle TCP state machine for this connection
398 1 switch (conxn[nr].state)
399 1 {
400 2 case STATE_CLOSED:
401 2 case STATE_LISTEN:
402 2
403 2 // If incoming segment contains SYN and no ACK, then handle
404 2 if ((tcp->flags & FLG_SYN) && ((tcp->flags & FLG_ACK) == 0))
405 2 {
406 3 // Capture his starting sequence number and generate
407 3 // my starting sequence number
408 3 // Fill in connection information
409 3 conxn[nr].ipaddr = ip->source_ipaddr;
410 3 conxn[nr].port = tcp->source_port;
411 3 conxn[nr].state = STATE_LISTEN;
412 3 conxn[nr].his_sequence = 1 + tcp->sequence;
413 3 conxn[nr].his_ack = tcp->ack_number;
414 3
415 3 // Use system clock for initial sequence number
416 3 EA = 0;
417 3 conxn[nr].my_sequence = initial_sequence_nr;
418 3 initial_sequence_nr += 64000L;
419 3 EA = 1;
420 3
421 3 // Send header options with the next message
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -