📄 tcp.lst
字号:
239 5 TCPRelease(pTCB);
240 5 }
241 4 else
C51 COMPILER V7.07 TCP 01/14/2009 14:46:37 PAGE 5
242 4 {
243 5 pTCB->RetranTimes++;
244 5 pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
245 5 }
246 4 }
247 3 else
248 3 pTCB->RetranTimer--;
249 3 }
250 2 }
251 1 }
252 /* when a TCP close, send too much packet but no replay,
253 connection fail. TCPIP will call TCPRelease to release packet
254 and queue, but will not reclaim TCB. in other word user
255 can use this socket again. */
256 void TCPRelease(struct STCB DT_XDATA *pTCB) REENTRANT_SIG
257 {
258 1 struct SPacketQueue DT_XDATA *pQ;
259 1
260 1 /* reclaim Q, and free packet in queue */
261 1 while(pQ = TCPOutQ(&(pTCB->QExceedSeq)))
262 1 MemFree(pQ->MemHead);
263 1 while(pQ = TCPOutQ(&(pTCB->QUnacked)))
264 1 MemFree(pQ->MemHead);
265 1 while(pQ = TCPOutQ(&(pTCB->QUnSend)))
266 1 MemFree(pQ->MemHead);
267 1 }
268
269 /* fill a segment and send it,NOTE MemHead->pStart point to TCPData */
270 BOOL TCPSendSeg(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead,BYTE TCPFlag) REENTRANT_SIG
271 {
272 1 struct STCPHead DT_XDATA *pTCPHead;
273 1 struct SIPHead DT_XDATA *pIPHead;
274 1 WORD SeqInc;
275 1
276 1 /* mem insufficient? */
277 1 if(MemHead == NULL)
278 1 return FALSE;
279 1
280 1 /* SeqMine increasment */
281 1 if((TCPFlag & TCP_SYN) || (TCPFlag & TCP_FIN))
282 1 {
283 2 SeqInc = MemHead->pEnd - MemHead->pStart + 1;
284 2 }
285 1 else
286 1 {
287 2 SeqInc = MemHead->pEnd - MemHead->pStart;
288 2 }
289 1
290 1 pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart - sizeof(struct STCPHead));
291 1
292 1 /* fill tcp header */
293 1 pTCPHead->PortDest = pTCB->PortDest;
294 1 pTCPHead->PortScr = pTCB->PortScr;
295 1 pTCPHead->Seq = htonl(pTCB->SeqMine);
296 1 pTCPHead->AckSeq = htonl(pTCB->SeqHis);
297 1 pTCPHead->TCPHeadLen = (BYTE)(((BYTE)sizeof(struct STCPHead)/4)<<4);
298 1 pTCPHead->flag = TCPFlag;
299 1 pTCPHead->WndSize = htons(pTCB->WndMine = MemFreeSize());
300 1 pTCPHead->CheckSum = 0;
301 1 pTCPHead->UrgentPoint = 0;
302 1
303 1 /* fill some of IPHead. it will be used to calculate TCPChecksum
C51 COMPILER V7.07 TCP 01/14/2009 14:46:37 PAGE 6
304 1 and as augument passed to IPlayer */
305 1 pIPHead = (struct SIPHead DT_XDATA *)((BYTE DT_XDATA *)pTCPHead - IP_HEAD_MIN_LEN);
306 1 pIPHead->IPDest = pTCB->IPDest;
307 1 pIPHead->IPScr = pTCB->IPScr;
308 1 pIPHead->Protocol = IP_PROTOCOL_TCP;
309 1 pIPHead->TotalLen = htons(MemHead->pEnd -
310 1 MemHead->pStart + TCP_HEAD_MIN_LEN + IP_HEAD_MIN_LEN); /* pStart point to TCP data */
311 1 pTCPHead->CheckSum = htons(TCPCheckSum(pIPHead,MemHead->pEnd - MemHead->pStart + TCP_HEAD_MIN_LEN));
312 1
313 1 /* send packet */
314 1 MemHead->pStart = (BYTE DT_XDATA *)pIPHead; /* dec pStart */
315 1 IPOutput(MemHead);
316 1
317 1 /*
318 1 * renew tcb
319 1 */
320 1 /* no ack need. because this packet will give a ack to him */
321 1 pTCB->bNeedAck = FALSE;
322 1
323 1 pTCB->SeqMine += SeqInc;
324 1
325 1 /* if this packet contant data or is a FIN or SYN packet
326 1 we write it to unacked queue */
327 1 if(SeqInc != 0)
328 1 {
329 2 /* if the unacked queue is empty, start timer for this packet */
330 2 if(pTCB->QUnacked == NULL)
331 2 {
332 3 pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
333 3 pTCB->RetranTimes = 0;
334 3 }
335 2
336 2 TCPInsertQ(&(pTCB->QUnacked),MemHead,htonl(pTCPHead->Seq));
337 2 }
338 1 else
339 1 {
340 2 MemFree(MemHead);
341 2 }
342 1 return TRUE;
343 1 }
344
345 /* judge his wnd if he can receive this packet. send call TCPSendSeg.
346 only send this seg completely return TRUE*/
347 BOOL TCPSendSegJudgeWnd(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_MUL
348 {
349 1 struct SMemHead DT_XDATA *NewMemHead;
350 1
351 1 /* if WndHis is large enough to receive this packet send it.
352 1 otherwise create a new packet and send part of Data. the remain
353 1 going to transmit when WndHis refresh at TCPInput */
354 1 if(MemHead->pEnd - MemHead->pStart > pTCB->WndHis)
355 1 {
356 2 /* part of Data need send */
357 2 if(pTCB->WndHis > 0)
358 2 {
359 3 /* create a new MemHead */
360 3 if((NewMemHead = TCPAllocate(pTCB->WndHis)) == NULL)
361 3 return FALSE;
362 3
363 3 /* copy part of data to new MemHead */
364 3 MemCopy(NewMemHead->pStart,MemHead->pStart,pTCB->WndHis);
365 3
C51 COMPILER V7.07 TCP 01/14/2009 14:46:37 PAGE 7
366 3 /* delete this part from old MemHead */
367 3 MemHead->pStart += pTCB->WndHis;
368 3
369 3 /* send the NewMemHead */
370 3 TCPSendSeg(pTCB,NewMemHead,TCP_ACK);
371 3
372 3 return FALSE;
373 3 }
374 2 else
375 2 {
376 3 /* can't send any data now */
377 3 return FALSE;
378 3 }
379 2 }
380 1 else
381 1 {
382 2 TCPSendSeg(pTCB,MemHead,TCP_ACK);
383 2 return TRUE;
384 2 }
385 1 }
386
387 /* send seg in unsend queue untill can't send any more. if send all
388 seg in queue return true */
389 BOOL TCPSendUnsendQ(struct STCB DT_XDATA *pTCB) REENTRANT_MUL
390 {
391 1 /* send every packet in unsend queue if can */
392 1 for(;pTCB->QUnSend != NULL;)
393 1 {
394 2 /* send it completely? */
395 2 if(TCPSendSegJudgeWnd(pTCB,pTCB->QUnSend->MemHead) == TRUE)
396 2 {
397 3 /* delete it from unsend queue */
398 3 TCPOutQ(&(pTCB->QUnSend));
399 3 }
400 2 else
401 2 {
402 3 /* only part of the seg is send */
403 3 return FALSE;
404 3 }
405 2 }
406 1 return TRUE;
407 1 }
408
409 /* call by TCPInput after judge this packet can be received.NOTE:MemHead-pStart point
410 to TCP head. TCPHead byte order is change in TCPInput */
411 void TCPRecvSeg(struct STCB DT_XDATA *pTCB,struct SMemHead DT_XDATA *MemHead) REENTRANT_SIG
412 {
413 1 WORD TCPDataSize;
414 1 struct STCB DT_XDATA *pNewTCB;
415 1 struct SIPHead DT_XDATA *pIPHead;
416 1 struct STCPHead DT_XDATA *pTCPHead;
417 1
418 1 pTCPHead = (struct STCPHead DT_XDATA *)(MemHead->pStart );
419 1 pIPHead = (struct SIPHead DT_XDATA *)(MemHead->pStart - IP_HEAD_MIN_LEN);
420 1
421 1 /*
422 1 * begain renew tcb values
423 1 */
424 1
425 1 /* dest windows size renew.*/
426 1 pTCB->WndHis = pTCPHead->WndSize;
427 1
C51 COMPILER V7.07 TCP 01/14/2009 14:46:37 PAGE 8
428 1 /* after dest windows renew is it possible to send a packet in unsend queue now ?*/
429 1 TCPSendUnsendQ(pTCB);
430 1
431 1 /* His Sequence renew */
432 1 TCPDataSize = ntohs(pIPHead->TotalLen) - IP_HEAD_MIN_LEN
433 1 - TCP_HEAD_LEN(pTCPHead);
434 1 if((pTCPHead->flag & TCP_SYN) || (pTCPHead->flag & TCP_FIN))
435 1 {
436 2 pTCB->SeqHis += TCPDataSize + 1;
437 2 }
438 1 else
439 1 {
440 2 pTCB->SeqHis += TCPDataSize;
441 2 }
442 1
443 1 /* NeedAck? */
444 1 if(TCPDataSize != 0)
445 1 {
446 2 pTCB->bNeedAck = TRUE;
447 2 pTCB->DelayAckTimer = TCP_DELAY_ACK_TIME_OUT;
448 2 }
449 1
450 1 /* if This packet acked packet in unacked queue */
451 1 if((pTCPHead->flag & TCP_ACK) != 0)
452 1 {
453 2 while(pTCB->QUnacked != NULL &&
454 2 TCP_SEQ_COMPARE(pTCB->QUnacked->Seq,pTCPHead->AckSeq) < 0)
455 2 {
456 3 MemFree(pTCB->QUnacked->MemHead);
457 3 TCPOutQ(&(pTCB->QUnacked));
458 3
459 3 /* timer for retran restore */
460 3 pTCB->RetranTimer = TCP_RETRAN_TIME_OUT;
461 3 pTCB->RetranTimes = 0;
462 3 }
463 2 }
464 1
465 1 /*
466 1 * deal refer to tcb.state and tcp flag
467 1 */
468 1 switch(pTCB->TCPState)
469 1 {
470 2 case TCP_STATE_CLOSED:
471 2 break;
472 2 case TCP_STATE_LISTEN:
473 2 /* syn: to TCP_STATE_SYNSENT, send syn+ack */
474 2 if(pTCPHead->flag == TCP_SYN)
475 2 {
476 3 /* create a new tcb and it is going to deal with
477 3 this connection. */
478 3 if((pNewTCB = TCPSocket(htonl(pTCB->IPScr))) == NULL)
479 3 {
480 4 MemFree(MemHead);
481 4 return;
482 4 }
483 3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -