Process the data and FIN flag, and check whether to deliver data to the socket layer. @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. @retval 0 No error occurred to deliver data. @retval -1 An error condition occurred. The proper response is to reset the connection. **/
| 390 | |
| 391 | **/ |
| 392 | INTN |
| 393 | TcpDeliverData ( |
| 394 | IN OUT TCP_CB *Tcb |
| 395 | ) |
| 396 | { |
| 397 | LIST_ENTRY *Entry; |
| 398 | NET_BUF *Nbuf; |
| 399 | TCP_SEQNO Seq; |
| 400 | TCP_SEG *Seg; |
| 401 | UINT32 Urgent; |
| 402 | |
| 403 | ASSERT ((Tcb != NULL) && (Tcb->Sk != NULL)); |
| 404 | |
| 405 | // |
| 406 | // make sure there is some data queued, |
| 407 | // and TCP is in a proper state |
| 408 | // |
| 409 | if (IsListEmpty (&Tcb->RcvQue) || !TCP_CONNECTED (Tcb->State)) { |
| 410 | |
| 411 | return 0; |
| 412 | } |
| 413 | |
| 414 | // |
| 415 | // Deliver data to the socket layer |
| 416 | // |
| 417 | Entry = Tcb->RcvQue.ForwardLink; |
| 418 | Seq = Tcb->RcvNxt; |
| 419 | |
| 420 | while (Entry != &Tcb->RcvQue) { |
| 421 | Nbuf = NET_LIST_USER_STRUCT (Entry, NET_BUF, List); |
| 422 | Seg = TCPSEG_NETBUF (Nbuf); |
| 423 | |
| 424 | if (TcpVerifySegment (Nbuf) == 0) { |
| 425 | DEBUG ( |
| 426 | (EFI_D_ERROR, |
| 427 | "TcpToSendData: discard a broken segment for TCB %p\n", |
| 428 | Tcb) |
| 429 | ); |
| 430 | NetbufFree (Nbuf); |
| 431 | return -1; |
| 432 | } |
| 433 | |
| 434 | ASSERT (Nbuf->Tcp == NULL); |
| 435 | |
| 436 | if (TCP_SEQ_GT (Seg->Seq, Seq)) { |
| 437 | break; |
| 438 | } |
| 439 | |
| 440 | Entry = Entry->ForwardLink; |
| 441 | Seq = Seg->End; |
| 442 | Tcb->RcvNxt = Seq; |
| 443 | |
| 444 | RemoveEntryList (&Nbuf->List); |
| 445 | |
| 446 | // |
| 447 | // RFC793 Eighth step: process FIN in sequence |
| 448 | // |
| 449 | if (TCP_FLG_ON (Seg->Flag, TCP_FLG_FIN)) { |
no test coverage detected