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