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