]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
1. Mark the network volatile variables as deprecated in code comments and remove...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Dispatcher.c
CommitLineData
8a67d61d 1/** @file\r
dab714aa 2 Tcp request dispatcher implementation.\r
8a67d61d 3\r
d551cc64 4Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
8a67d61d 6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
dfc1f033 8http://opensource.org/licenses/bsd-license.php<BR>\r
8a67d61d 9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
8a67d61d 13**/\r
14\r
15#include "Tcp4Main.h"\r
16\r
17#define TCP_COMP_VAL(Min, Max, Default, Val) \\r
18 ((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default))\r
19\r
120db52c 20/**\r
21 Add or remove a route entry in the IP route table associated with this TCP instance.\r
22\r
23 @param Tcb Pointer to the TCP_CB of this TCP instance.\r
24 @param RouteInfo Pointer to the route info to be processed.\r
25\r
26 @retval EFI_SUCCESS The operation completed successfully.\r
27 @retval EFI_NOT_STARTED The driver instance has not been started.\r
28 @retval EFI_NO_MAPPING When using the default address, configuration(DHCP,\r
29 BOOTP, RARP, etc.) is not finished yet.\r
30 @retval EFI_OUT_OF_RESOURCES Could not add the entry to the routing table.\r
31 @retval EFI_NOT_FOUND This route is not in the routing table\r
32 (when RouteInfo->DeleteRoute is TRUE).\r
33 @retval EFI_ACCESS_DENIED The route is already defined in the routing table\r
34 (when RouteInfo->DeleteRoute is FALSE).\r
35**/\r
8a67d61d 36EFI_STATUS\r
37Tcp4Route (\r
38 IN TCP_CB *Tcb,\r
39 IN TCP4_ROUTE_INFO *RouteInfo\r
40 )\r
8a67d61d 41{\r
2a2e33b2 42 EFI_IP4_PROTOCOL *Ip4;\r
8a67d61d 43\r
2a2e33b2 44 Ip4 = Tcb->IpInfo->Ip.Ip4;\r
8a67d61d 45\r
2a2e33b2 46 ASSERT (Ip4 != NULL);\r
8a67d61d 47\r
2a2e33b2 48 return Ip4->Routes (\r
49 Ip4,\r
8a67d61d 50 RouteInfo->DeleteRoute,\r
51 RouteInfo->SubnetAddress,\r
52 RouteInfo->SubnetMask,\r
53 RouteInfo->GatewayAddress\r
54 );\r
e2851998 55\r
8a67d61d 56}\r
57\r
58\r
59/**\r
60 Get the operational settings of this TCP instance.\r
61\r
62 @param Tcb Pointer to the TCP_CB of this TCP instance.\r
63 @param Mode Pointer to the buffer to store the operational\r
64 settings.\r
65\r
66 @retval EFI_SUCCESS The mode data is read.\r
67 @retval EFI_NOT_STARTED No configuration data is available because this\r
68 instance hasn't been started.\r
69\r
70**/\r
8a67d61d 71EFI_STATUS\r
72Tcp4GetMode (\r
276dcc1b 73 IN TCP_CB *Tcb,\r
74 IN OUT TCP4_MODE_DATA *Mode\r
8a67d61d 75 )\r
76{\r
77 SOCKET *Sock;\r
78 EFI_TCP4_CONFIG_DATA *ConfigData;\r
79 EFI_TCP4_ACCESS_POINT *AccessPoint;\r
80 EFI_TCP4_OPTION *Option;\r
81 EFI_IP4_PROTOCOL *Ip;\r
82\r
83 Sock = Tcb->Sk;\r
84\r
85 if (!SOCK_IS_CONFIGURED (Sock) && (Mode->Tcp4ConfigData != NULL)) {\r
86 return EFI_NOT_STARTED;\r
87 }\r
88\r
85511ddf 89 if (Mode->Tcp4State != NULL) {\r
4eb65aff 90 *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State;\r
8a67d61d 91 }\r
92\r
85511ddf 93 if (Mode->Tcp4ConfigData != NULL) {\r
8a67d61d 94\r
95 ConfigData = Mode->Tcp4ConfigData;\r
96 AccessPoint = &(ConfigData->AccessPoint);\r
97 Option = ConfigData->ControlOption;\r
98\r
a78d176c 99 ConfigData->TypeOfService = Tcb->Tos;\r
100 ConfigData->TimeToLive = Tcb->Ttl;\r
8a67d61d 101\r
102 AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;\r
103\r
e48e37fc 104 CopyMem (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
8a67d61d 105 AccessPoint->SubnetMask = Tcb->SubnetMask;\r
106 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r
107\r
e48e37fc 108 CopyMem (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
8a67d61d 109 AccessPoint->RemotePort = NTOHS (Tcb->RemoteEnd.Port);\r
110 AccessPoint->ActiveFlag = (BOOLEAN) (Tcb->State != TCP_LISTEN);\r
111\r
112 if (Option != NULL) {\r
113 Option->ReceiveBufferSize = GET_RCV_BUFFSIZE (Tcb->Sk);\r
114 Option->SendBufferSize = GET_SND_BUFFSIZE (Tcb->Sk);\r
115 Option->MaxSynBackLog = GET_BACKLOG (Tcb->Sk);\r
116\r
117 Option->ConnectionTimeout = Tcb->ConnectTimeout / TCP_TICK_HZ;\r
118 Option->DataRetries = Tcb->MaxRexmit;\r
119 Option->FinTimeout = Tcb->FinWait2Timeout / TCP_TICK_HZ;\r
120 Option->TimeWaitTimeout = Tcb->TimeWaitTimeout / TCP_TICK_HZ;\r
121 Option->KeepAliveProbes = Tcb->MaxKeepAlive;\r
122 Option->KeepAliveTime = Tcb->KeepAliveIdle / TCP_TICK_HZ;\r
123 Option->KeepAliveInterval = Tcb->KeepAlivePeriod / TCP_TICK_HZ;\r
124\r
4eb65aff 125 Option->EnableNagle = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE));\r
126 Option->EnableTimeStamp = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_TS));\r
ed66e1bc 127 Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));\r
8a67d61d 128\r
129 Option->EnableSelectiveAck = FALSE;\r
130 Option->EnablePathMtuDiscovery = FALSE;\r
131 }\r
132 }\r
133\r
2a2e33b2 134 Ip = Tcb->IpInfo->Ip.Ip4;\r
120db52c 135 ASSERT (Ip != NULL);\r
8a67d61d 136\r
137 return Ip->GetModeData (Ip, Mode->Ip4ModeData, Mode->MnpConfigData, Mode->SnpModeData);\r
138}\r
139\r
140\r
141/**\r
142 If AP->StationPort isn't zero, check whether the access point\r
143 is registered, else generate a random station port for this\r
144 access point.\r
145\r
146 @param AP Pointer to the access point.\r
147\r
148 @retval EFI_SUCCESS The check is passed or the port is assigned.\r
149 @retval EFI_INVALID_PARAMETER The non-zero station port is already used.\r
150 @retval EFI_OUT_OF_RESOURCES No port can be allocated.\r
151\r
152**/\r
8a67d61d 153EFI_STATUS\r
154Tcp4Bind (\r
155 IN EFI_TCP4_ACCESS_POINT *AP\r
156 )\r
157{\r
158 BOOLEAN Cycle;\r
159\r
160 if (0 != AP->StationPort) {\r
161 //\r
162 // check if a same endpoint is bound\r
163 //\r
164 if (TcpFindTcbByPeer (&AP->StationAddress, AP->StationPort)) {\r
165\r
166 return EFI_INVALID_PARAMETER;\r
167 }\r
168 } else {\r
169 //\r
170 // generate a random port\r
171 //\r
172 Cycle = FALSE;\r
173\r
174 if (TCP4_PORT_USER_RESERVED == mTcp4RandomPort) {\r
175 mTcp4RandomPort = TCP4_PORT_KNOWN;\r
176 }\r
177\r
178 mTcp4RandomPort++;\r
179\r
180 while (TcpFindTcbByPeer (&AP->StationAddress, mTcp4RandomPort)) {\r
181\r
182 mTcp4RandomPort++;\r
183\r
184 if (mTcp4RandomPort <= TCP4_PORT_KNOWN) {\r
185\r
186 if (Cycle) {\r
e48e37fc 187 DEBUG ((EFI_D_ERROR, "Tcp4Bind: no port can be allocated "\r
8a67d61d 188 "for this pcb\n"));\r
189\r
190 return EFI_OUT_OF_RESOURCES;\r
191 }\r
192\r
193 mTcp4RandomPort = TCP4_PORT_KNOWN + 1;\r
194\r
195 Cycle = TRUE;\r
196 }\r
197\r
198 }\r
199\r
200 AP->StationPort = mTcp4RandomPort;\r
201 }\r
202\r
203 return EFI_SUCCESS;\r
204}\r
205\r
206\r
207/**\r
85511ddf 208 Flush the Tcb add its associated protocols.\r
8a67d61d 209\r
210 @param Tcb Pointer to the TCP_CB to be flushed.\r
211\r
120db52c 212**/\r
8a67d61d 213VOID\r
214Tcp4FlushPcb (\r
215 IN TCP_CB *Tcb\r
216 )\r
217{\r
218 SOCKET *Sock;\r
219 TCP4_PROTO_DATA *TcpProto;\r
220\r
221 IpIoConfigIp (Tcb->IpInfo, NULL);\r
222\r
223 Sock = Tcb->Sk;\r
224 TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
225\r
226 if (SOCK_IS_CONFIGURED (Sock)) {\r
e48e37fc 227 RemoveEntryList (&Tcb->List);\r
8a67d61d 228\r
e5e12de7 229 //\r
29056ed2 230 // Uninstall the device path protocol.\r
e5e12de7 231 //\r
29056ed2 232 if (Sock->DevicePath != NULL) {\r
233 gBS->UninstallProtocolInterface (\r
234 Sock->SockHandle,\r
235 &gEfiDevicePathProtocolGuid,\r
236 Sock->DevicePath\r
237 );\r
238 FreePool (Sock->DevicePath);\r
239 }\r
8a67d61d 240 }\r
241\r
242 NetbufFreeList (&Tcb->SndQue);\r
243 NetbufFreeList (&Tcb->RcvQue);\r
54ea3ede 244 Tcb->State = TCP_CLOSED;\r
8a67d61d 245}\r
246\r
120db52c 247/**\r
dfc1f033 248 Attach a Pcb to the socket.\r
120db52c 249\r
250 @param Sk Pointer to the socket of this TCP instance.\r
e2851998 251\r
120db52c 252 @retval EFI_SUCCESS The operation is completed successfully.\r
253 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
254\r
255**/\r
8a67d61d 256EFI_STATUS\r
257Tcp4AttachPcb (\r
258 IN SOCKET *Sk\r
259 )\r
260{\r
261 TCP_CB *Tcb;\r
262 TCP4_PROTO_DATA *ProtoData;\r
263 IP_IO *IpIo;\r
216f7970 264 EFI_STATUS Status;\r
265 VOID *Ip;\r
8a67d61d 266\r
e48e37fc 267 Tcb = AllocateZeroPool (sizeof (TCP_CB));\r
8a67d61d 268\r
269 if (Tcb == NULL) {\r
270\r
e48e37fc 271 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));\r
8a67d61d 272\r
273 return EFI_OUT_OF_RESOURCES;\r
274 }\r
275\r
276 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
277 IpIo = ProtoData->TcpService->IpIo;\r
278\r
279 //\r
280 // Create an IpInfo for this Tcb.\r
281 //\r
282 Tcb->IpInfo = IpIoAddIp (IpIo);\r
283 if (Tcb->IpInfo == NULL) {\r
284\r
766c7483 285 FreePool (Tcb);\r
8a67d61d 286 return EFI_OUT_OF_RESOURCES;\r
287 }\r
288\r
216f7970 289 //\r
290 // Open the new created IP instance BY_CHILD.\r
291 //\r
292 Status = gBS->OpenProtocol (\r
293 Tcb->IpInfo->ChildHandle,\r
294 &gEfiIp4ProtocolGuid,\r
295 &Ip,\r
296 IpIo->Image,\r
297 Sk->SockHandle,\r
298 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
299 );\r
300 if (EFI_ERROR (Status)) {\r
301 IpIoRemoveIp (IpIo, Tcb->IpInfo);\r
302 return Status;\r
303 }\r
304\r
e48e37fc 305 InitializeListHead (&Tcb->List);\r
306 InitializeListHead (&Tcb->SndQue);\r
307 InitializeListHead (&Tcb->RcvQue);\r
8a67d61d 308\r
309 Tcb->State = TCP_CLOSED;\r
310 Tcb->Sk = Sk;\r
311 ProtoData->TcpPcb = Tcb;\r
312\r
313 return EFI_SUCCESS;\r
314}\r
315\r
120db52c 316/**\r
dfc1f033 317 Detach the Pcb of the socket.\r
120db52c 318\r
319 @param Sk Pointer to the socket of this TCP instance.\r
e2851998 320\r
120db52c 321**/\r
8a67d61d 322VOID\r
323Tcp4DetachPcb (\r
324 IN SOCKET *Sk\r
325 )\r
326{\r
327 TCP4_PROTO_DATA *ProtoData;\r
328 TCP_CB *Tcb;\r
329\r
330 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
331 Tcb = ProtoData->TcpPcb;\r
332\r
333 ASSERT (Tcb != NULL);\r
334\r
335 Tcp4FlushPcb (Tcb);\r
336\r
216f7970 337 //\r
338 // Close the IP protocol.\r
339 //\r
340 gBS->CloseProtocol (\r
341 Tcb->IpInfo->ChildHandle,\r
342 &gEfiIp4ProtocolGuid,\r
343 ProtoData->TcpService->IpIo->Image,\r
344 Sk->SockHandle\r
345 );\r
346 \r
8a67d61d 347 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r
348\r
766c7483 349 FreePool (Tcb);\r
8a67d61d 350\r
351 ProtoData->TcpPcb = NULL;\r
352}\r
353\r
354\r
355/**\r
dfc1f033 356 Configure the Pcb using CfgData.\r
8a67d61d 357\r
358 @param Sk Pointer to the socket of this TCP instance.\r
8a67d61d 359 @param CfgData Pointer to the TCP configuration data.\r
360\r
361 @retval EFI_SUCCESS The operation is completed successfully.\r
362 @retval EFI_INVALID_PARAMETER A same access point has been configured in\r
363 another TCP instance.\r
364 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
365\r
366**/\r
8a67d61d 367EFI_STATUS\r
368Tcp4ConfigurePcb (\r
369 IN SOCKET *Sk,\r
370 IN EFI_TCP4_CONFIG_DATA *CfgData\r
371 )\r
372{\r
8a67d61d 373 EFI_IP4_CONFIG_DATA IpCfgData;\r
374 EFI_STATUS Status;\r
375 EFI_TCP4_OPTION *Option;\r
376 TCP4_PROTO_DATA *TcpProto;\r
377 TCP_CB *Tcb;\r
378\r
120db52c 379 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));\r
8a67d61d 380\r
381 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
382 Tcb = TcpProto->TcpPcb;\r
8a67d61d 383\r
384 ASSERT (Tcb != NULL);\r
385\r
386 //\r
387 // Add Ip for send pkt to the peer\r
388 //\r
fb115c61 389 CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));\r
8a67d61d 390 IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
391 IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;\r
392 IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;\r
393 IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;\r
394 IpCfgData.ReceiveTimeout = (UINT32) (-1);\r
395\r
396 //\r
397 // Configure the IP instance this Tcb consumes.\r
398 //\r
399 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);\r
400 if (EFI_ERROR (Status)) {\r
401 goto OnExit;\r
402 }\r
403\r
404 //\r
405 // Get the default address info if the instance is configured to use default address.\r
406 //\r
407 if (CfgData->AccessPoint.UseDefaultAddress) {\r
408 CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;\r
409 CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;\r
410 }\r
411\r
412 //\r
413 // check if we can bind this endpoint in CfgData\r
414 //\r
415 Status = Tcp4Bind (&(CfgData->AccessPoint));\r
416\r
417 if (EFI_ERROR (Status)) {\r
e48e37fc 418 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "\r
8a67d61d 419 "with %r\n", Status));\r
420\r
421 goto OnExit;\r
422 }\r
423\r
424 //\r
425 // Initalize the operating information in this Tcb\r
426 //\r
427 ASSERT (Tcb->State == TCP_CLOSED &&\r
e48e37fc 428 IsListEmpty (&Tcb->SndQue) &&\r
429 IsListEmpty (&Tcb->RcvQue));\r
8a67d61d 430\r
431 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
432 Tcb->State = TCP_CLOSED;\r
433\r
434 Tcb->SndMss = 536;\r
435 Tcb->RcvMss = TcpGetRcvMss (Sk);\r
436\r
437 Tcb->SRtt = 0;\r
438 Tcb->Rto = 3 * TCP_TICK_HZ;\r
439\r
440 Tcb->CWnd = Tcb->SndMss;\r
441 Tcb->Ssthresh = 0xffffffff;\r
442\r
443 Tcb->CongestState = TCP_CONGEST_OPEN;\r
444\r
445 Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;\r
446 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;\r
447 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;\r
448 Tcb->MaxRexmit = TCP_MAX_LOSS;\r
449 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;\r
450 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;\r
451 Tcb->ConnectTimeout = TCP_CONNECT_TIME;\r
452\r
453 //\r
454 // initialize Tcb in the light of CfgData\r
455 //\r
a78d176c 456 Tcb->Ttl = CfgData->TimeToLive;\r
457 Tcb->Tos = CfgData->TypeOfService;\r
8a67d61d 458\r
e5e12de7 459 Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;\r
460\r
e48e37fc 461 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));\r
8a67d61d 462 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);\r
463 Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;\r
464\r
e5e12de7 465 if (CfgData->AccessPoint.ActiveFlag) {\r
e48e37fc 466 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r
e5e12de7 467 Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);\r
468 } else {\r
469 Tcb->RemoteEnd.Ip = 0;\r
470 Tcb->RemoteEnd.Port = 0;\r
471 }\r
8a67d61d 472\r
473 Option = CfgData->ControlOption;\r
474\r
475 if (Option != NULL) {\r
476 SET_RCV_BUFFSIZE (\r
477 Sk,\r
4eb65aff 478 (UINT32) (TCP_COMP_VAL (\r
479 TCP_RCV_BUF_SIZE_MIN,\r
480 TCP_RCV_BUF_SIZE,\r
481 TCP_RCV_BUF_SIZE,\r
482 Option->ReceiveBufferSize\r
483 )\r
484 )\r
8a67d61d 485 );\r
486 SET_SND_BUFFSIZE (\r
487 Sk,\r
4eb65aff 488 (UINT32) (TCP_COMP_VAL (\r
489 TCP_SND_BUF_SIZE_MIN,\r
490 TCP_SND_BUF_SIZE,\r
491 TCP_SND_BUF_SIZE,\r
492 Option->SendBufferSize\r
493 )\r
494 )\r
8a67d61d 495 );\r
496\r
497 SET_BACKLOG (\r
498 Sk,\r
4eb65aff 499 (UINT32) (TCP_COMP_VAL (\r
500 TCP_BACKLOG_MIN,\r
501 TCP_BACKLOG,\r
502 TCP_BACKLOG,\r
503 Option->MaxSynBackLog\r
504 )\r
505 )\r
8a67d61d 506 );\r
507\r
508 Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (\r
509 TCP_MAX_LOSS_MIN,\r
510 TCP_MAX_LOSS,\r
511 TCP_MAX_LOSS,\r
512 Option->DataRetries\r
513 );\r
514 Tcb->FinWait2Timeout = TCP_COMP_VAL (\r
515 TCP_FIN_WAIT2_TIME,\r
516 TCP_FIN_WAIT2_TIME_MAX,\r
517 TCP_FIN_WAIT2_TIME,\r
4eb65aff 518 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)\r
8a67d61d 519 );\r
520\r
521 if (Option->TimeWaitTimeout != 0) {\r
522 Tcb->TimeWaitTimeout = TCP_COMP_VAL (\r
523 TCP_TIME_WAIT_TIME,\r
524 TCP_TIME_WAIT_TIME_MAX,\r
525 TCP_TIME_WAIT_TIME,\r
4eb65aff 526 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)\r
8a67d61d 527 );\r
528 } else {\r
529 Tcb->TimeWaitTimeout = 0;\r
530 }\r
531\r
532 if (Option->KeepAliveProbes != 0) {\r
533 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
534\r
535 Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (\r
536 TCP_MAX_KEEPALIVE_MIN,\r
537 TCP_MAX_KEEPALIVE,\r
538 TCP_MAX_KEEPALIVE,\r
539 Option->KeepAliveProbes\r
540 );\r
541 Tcb->KeepAliveIdle = TCP_COMP_VAL (\r
542 TCP_KEEPALIVE_IDLE_MIN,\r
543 TCP_KEEPALIVE_IDLE_MAX,\r
544 TCP_KEEPALIVE_IDLE_MIN,\r
4eb65aff 545 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)\r
8a67d61d 546 );\r
547 Tcb->KeepAlivePeriod = TCP_COMP_VAL (\r
548 TCP_KEEPALIVE_PERIOD_MIN,\r
549 TCP_KEEPALIVE_PERIOD,\r
550 TCP_KEEPALIVE_PERIOD,\r
4eb65aff 551 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)\r
8a67d61d 552 );\r
553 }\r
554\r
555 Tcb->ConnectTimeout = TCP_COMP_VAL (\r
556 TCP_CONNECT_TIME_MIN,\r
557 TCP_CONNECT_TIME,\r
558 TCP_CONNECT_TIME,\r
4eb65aff 559 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)\r
8a67d61d 560 );\r
561\r
e2851998 562 if (!Option->EnableNagle) {\r
8a67d61d 563 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);\r
564 }\r
565\r
e2851998 566 if (!Option->EnableTimeStamp) {\r
8a67d61d 567 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);\r
568 }\r
569\r
e2851998 570 if (!Option->EnableWindowScaling) {\r
8a67d61d 571 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);\r
572 }\r
573 }\r
574\r
e5e12de7 575 //\r
576 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is\r
577 // determined, construct the IP device path and install it.\r
578 //\r
579 Status = TcpInstallDevicePath (Sk);\r
580 if (EFI_ERROR (Status)) {\r
581 goto OnExit;\r
582 }\r
583\r
8a67d61d 584 //\r
585 // update state of Tcb and socket\r
586 //\r
e2851998 587 if (!CfgData->AccessPoint.ActiveFlag) {\r
8a67d61d 588\r
589 TcpSetState (Tcb, TCP_LISTEN);\r
590 SockSetState (Sk, SO_LISTENING);\r
591\r
592 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;\r
593 } else {\r
594\r
595 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;\r
596 }\r
597\r
598 TcpInsertTcb (Tcb);\r
599\r
600OnExit:\r
601\r
602 return Status;\r
603}\r
604\r
605\r
606/**\r
607 The procotol handler provided to the socket layer, used to\r
608 dispatch the socket level requests by calling the corresponding\r
609 TCP layer functions.\r
610\r
611 @param Sock Pointer to the socket of this TCP instance.\r
612 @param Request The code of this operation request.\r
613 @param Data Pointer to the operation specific data passed in\r
614 together with the operation request.\r
615\r
616 @retval EFI_SUCCESS The socket request is completed successfully.\r
617 @retval other The error status returned by the corresponding TCP\r
618 layer function.\r
619\r
620**/\r
621EFI_STATUS\r
622Tcp4Dispatcher (\r
623 IN SOCKET *Sock,\r
f6b7393c 624 IN UINT8 Request,\r
8a67d61d 625 IN VOID *Data OPTIONAL\r
626 )\r
627{\r
628 TCP_CB *Tcb;\r
629 TCP4_PROTO_DATA *ProtoData;\r
630 EFI_IP4_PROTOCOL *Ip;\r
631\r
632 ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
633 Tcb = ProtoData->TcpPcb;\r
634\r
635 switch (Request) {\r
636 case SOCK_POLL:\r
2a2e33b2 637 Ip = ProtoData->TcpService->IpIo->Ip.Ip4;\r
8a67d61d 638 Ip->Poll (Ip);\r
639 break;\r
640\r
641 case SOCK_CONSUMED:\r
642 //\r
643 // After user received data from socket buffer, socket will\r
644 // notify TCP using this message to give it a chance to send out\r
645 // window update information\r
646 //\r
120db52c 647 ASSERT (Tcb != NULL);\r
8a67d61d 648 TcpOnAppConsume (Tcb);\r
649 break;\r
650\r
651 case SOCK_SND:\r
652\r
120db52c 653 ASSERT (Tcb != NULL);\r
8a67d61d 654 TcpOnAppSend (Tcb);\r
655 break;\r
656\r
657 case SOCK_CLOSE:\r
658\r
659 TcpOnAppClose (Tcb);\r
660\r
661 break;\r
662\r
663 case SOCK_ABORT:\r
664\r
665 TcpOnAppAbort (Tcb);\r
666\r
667 break;\r
668\r
669 case SOCK_SNDPUSH:\r
670 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);\r
671 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);\r
672\r
673 break;\r
674\r
675 case SOCK_SNDURG:\r
676 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;\r
677 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r
678\r
679 break;\r
680\r
681 case SOCK_CONNECT:\r
682\r
683 TcpOnAppConnect (Tcb);\r
684\r
685 break;\r
686\r
687 case SOCK_ATTACH:\r
688\r
689 return Tcp4AttachPcb (Sock);\r
690\r
8a67d61d 691 case SOCK_FLUSH:\r
692\r
693 Tcp4FlushPcb (Tcb);\r
694\r
695 break;\r
696\r
697 case SOCK_DETACH:\r
698\r
699 Tcp4DetachPcb (Sock);\r
700\r
701 break;\r
702\r
703 case SOCK_CONFIGURE:\r
704\r
705 return Tcp4ConfigurePcb (\r
706 Sock,\r
707 (EFI_TCP4_CONFIG_DATA *) Data\r
708 );\r
709\r
8a67d61d 710 case SOCK_MODE:\r
711\r
120db52c 712 ASSERT ((Data != NULL) && (Tcb != NULL));\r
8a67d61d 713\r
714 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);\r
715\r
8a67d61d 716 case SOCK_ROUTE:\r
717\r
120db52c 718 ASSERT ((Data != NULL) && (Tcb != NULL));\r
8a67d61d 719\r
720 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);\r
721\r
b61439a7 722 default:\r
723 return EFI_UNSUPPORTED;\r
8a67d61d 724 }\r
725\r
726 return EFI_SUCCESS;\r
727\r
728}\r