]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
1. Add EFI_COMPONENT_NAME2_PROTOCOL.GetControllerName() support.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Dispatcher.c
CommitLineData
8a67d61d 1/** @file\r
dab714aa 2 Tcp request dispatcher implementation.\r
8a67d61d 3\r
216f7970 4Copyright (c) 2005 - 2012, 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
e5e12de7 240\r
8a67d61d 241 TcpSetVariableData (TcpProto->TcpService);\r
242 }\r
243\r
244 NetbufFreeList (&Tcb->SndQue);\r
245 NetbufFreeList (&Tcb->RcvQue);\r
54ea3ede 246 Tcb->State = TCP_CLOSED;\r
8a67d61d 247}\r
248\r
120db52c 249/**\r
dfc1f033 250 Attach a Pcb to the socket.\r
120db52c 251\r
252 @param Sk Pointer to the socket of this TCP instance.\r
e2851998 253\r
120db52c 254 @retval EFI_SUCCESS The operation is completed successfully.\r
255 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
256\r
257**/\r
8a67d61d 258EFI_STATUS\r
259Tcp4AttachPcb (\r
260 IN SOCKET *Sk\r
261 )\r
262{\r
263 TCP_CB *Tcb;\r
264 TCP4_PROTO_DATA *ProtoData;\r
265 IP_IO *IpIo;\r
216f7970 266 EFI_STATUS Status;\r
267 VOID *Ip;\r
8a67d61d 268\r
e48e37fc 269 Tcb = AllocateZeroPool (sizeof (TCP_CB));\r
8a67d61d 270\r
271 if (Tcb == NULL) {\r
272\r
e48e37fc 273 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));\r
8a67d61d 274\r
275 return EFI_OUT_OF_RESOURCES;\r
276 }\r
277\r
278 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
279 IpIo = ProtoData->TcpService->IpIo;\r
280\r
281 //\r
282 // Create an IpInfo for this Tcb.\r
283 //\r
284 Tcb->IpInfo = IpIoAddIp (IpIo);\r
285 if (Tcb->IpInfo == NULL) {\r
286\r
766c7483 287 FreePool (Tcb);\r
8a67d61d 288 return EFI_OUT_OF_RESOURCES;\r
289 }\r
290\r
216f7970 291 //\r
292 // Open the new created IP instance BY_CHILD.\r
293 //\r
294 Status = gBS->OpenProtocol (\r
295 Tcb->IpInfo->ChildHandle,\r
296 &gEfiIp4ProtocolGuid,\r
297 &Ip,\r
298 IpIo->Image,\r
299 Sk->SockHandle,\r
300 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
301 );\r
302 if (EFI_ERROR (Status)) {\r
303 IpIoRemoveIp (IpIo, Tcb->IpInfo);\r
304 return Status;\r
305 }\r
306\r
e48e37fc 307 InitializeListHead (&Tcb->List);\r
308 InitializeListHead (&Tcb->SndQue);\r
309 InitializeListHead (&Tcb->RcvQue);\r
8a67d61d 310\r
311 Tcb->State = TCP_CLOSED;\r
312 Tcb->Sk = Sk;\r
313 ProtoData->TcpPcb = Tcb;\r
314\r
315 return EFI_SUCCESS;\r
316}\r
317\r
120db52c 318/**\r
dfc1f033 319 Detach the Pcb of the socket.\r
120db52c 320\r
321 @param Sk Pointer to the socket of this TCP instance.\r
e2851998 322\r
120db52c 323**/\r
8a67d61d 324VOID\r
325Tcp4DetachPcb (\r
326 IN SOCKET *Sk\r
327 )\r
328{\r
329 TCP4_PROTO_DATA *ProtoData;\r
330 TCP_CB *Tcb;\r
331\r
332 ProtoData = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
333 Tcb = ProtoData->TcpPcb;\r
334\r
335 ASSERT (Tcb != NULL);\r
336\r
337 Tcp4FlushPcb (Tcb);\r
338\r
216f7970 339 //\r
340 // Close the IP protocol.\r
341 //\r
342 gBS->CloseProtocol (\r
343 Tcb->IpInfo->ChildHandle,\r
344 &gEfiIp4ProtocolGuid,\r
345 ProtoData->TcpService->IpIo->Image,\r
346 Sk->SockHandle\r
347 );\r
348 \r
8a67d61d 349 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r
350\r
766c7483 351 FreePool (Tcb);\r
8a67d61d 352\r
353 ProtoData->TcpPcb = NULL;\r
354}\r
355\r
356\r
357/**\r
dfc1f033 358 Configure the Pcb using CfgData.\r
8a67d61d 359\r
360 @param Sk Pointer to the socket of this TCP instance.\r
8a67d61d 361 @param CfgData Pointer to the TCP configuration data.\r
362\r
363 @retval EFI_SUCCESS The operation is completed successfully.\r
364 @retval EFI_INVALID_PARAMETER A same access point has been configured in\r
365 another TCP instance.\r
366 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
367\r
368**/\r
8a67d61d 369EFI_STATUS\r
370Tcp4ConfigurePcb (\r
371 IN SOCKET *Sk,\r
372 IN EFI_TCP4_CONFIG_DATA *CfgData\r
373 )\r
374{\r
8a67d61d 375 EFI_IP4_CONFIG_DATA IpCfgData;\r
376 EFI_STATUS Status;\r
377 EFI_TCP4_OPTION *Option;\r
378 TCP4_PROTO_DATA *TcpProto;\r
379 TCP_CB *Tcb;\r
380\r
120db52c 381 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));\r
8a67d61d 382\r
383 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
384 Tcb = TcpProto->TcpPcb;\r
8a67d61d 385\r
386 ASSERT (Tcb != NULL);\r
387\r
388 //\r
389 // Add Ip for send pkt to the peer\r
390 //\r
fb115c61 391 CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));\r
8a67d61d 392 IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
393 IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;\r
394 IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;\r
395 IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;\r
396 IpCfgData.ReceiveTimeout = (UINT32) (-1);\r
397\r
398 //\r
399 // Configure the IP instance this Tcb consumes.\r
400 //\r
401 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);\r
402 if (EFI_ERROR (Status)) {\r
403 goto OnExit;\r
404 }\r
405\r
406 //\r
407 // Get the default address info if the instance is configured to use default address.\r
408 //\r
409 if (CfgData->AccessPoint.UseDefaultAddress) {\r
410 CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;\r
411 CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;\r
412 }\r
413\r
414 //\r
415 // check if we can bind this endpoint in CfgData\r
416 //\r
417 Status = Tcp4Bind (&(CfgData->AccessPoint));\r
418\r
419 if (EFI_ERROR (Status)) {\r
e48e37fc 420 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "\r
8a67d61d 421 "with %r\n", Status));\r
422\r
423 goto OnExit;\r
424 }\r
425\r
426 //\r
427 // Initalize the operating information in this Tcb\r
428 //\r
429 ASSERT (Tcb->State == TCP_CLOSED &&\r
e48e37fc 430 IsListEmpty (&Tcb->SndQue) &&\r
431 IsListEmpty (&Tcb->RcvQue));\r
8a67d61d 432\r
433 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
434 Tcb->State = TCP_CLOSED;\r
435\r
436 Tcb->SndMss = 536;\r
437 Tcb->RcvMss = TcpGetRcvMss (Sk);\r
438\r
439 Tcb->SRtt = 0;\r
440 Tcb->Rto = 3 * TCP_TICK_HZ;\r
441\r
442 Tcb->CWnd = Tcb->SndMss;\r
443 Tcb->Ssthresh = 0xffffffff;\r
444\r
445 Tcb->CongestState = TCP_CONGEST_OPEN;\r
446\r
447 Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;\r
448 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;\r
449 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;\r
450 Tcb->MaxRexmit = TCP_MAX_LOSS;\r
451 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;\r
452 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;\r
453 Tcb->ConnectTimeout = TCP_CONNECT_TIME;\r
454\r
455 //\r
456 // initialize Tcb in the light of CfgData\r
457 //\r
a78d176c 458 Tcb->Ttl = CfgData->TimeToLive;\r
459 Tcb->Tos = CfgData->TypeOfService;\r
8a67d61d 460\r
e5e12de7 461 Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;\r
462\r
e48e37fc 463 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));\r
8a67d61d 464 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);\r
465 Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;\r
466\r
e5e12de7 467 if (CfgData->AccessPoint.ActiveFlag) {\r
e48e37fc 468 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r
e5e12de7 469 Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);\r
470 } else {\r
471 Tcb->RemoteEnd.Ip = 0;\r
472 Tcb->RemoteEnd.Port = 0;\r
473 }\r
8a67d61d 474\r
475 Option = CfgData->ControlOption;\r
476\r
477 if (Option != NULL) {\r
478 SET_RCV_BUFFSIZE (\r
479 Sk,\r
4eb65aff 480 (UINT32) (TCP_COMP_VAL (\r
481 TCP_RCV_BUF_SIZE_MIN,\r
482 TCP_RCV_BUF_SIZE,\r
483 TCP_RCV_BUF_SIZE,\r
484 Option->ReceiveBufferSize\r
485 )\r
486 )\r
8a67d61d 487 );\r
488 SET_SND_BUFFSIZE (\r
489 Sk,\r
4eb65aff 490 (UINT32) (TCP_COMP_VAL (\r
491 TCP_SND_BUF_SIZE_MIN,\r
492 TCP_SND_BUF_SIZE,\r
493 TCP_SND_BUF_SIZE,\r
494 Option->SendBufferSize\r
495 )\r
496 )\r
8a67d61d 497 );\r
498\r
499 SET_BACKLOG (\r
500 Sk,\r
4eb65aff 501 (UINT32) (TCP_COMP_VAL (\r
502 TCP_BACKLOG_MIN,\r
503 TCP_BACKLOG,\r
504 TCP_BACKLOG,\r
505 Option->MaxSynBackLog\r
506 )\r
507 )\r
8a67d61d 508 );\r
509\r
510 Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (\r
511 TCP_MAX_LOSS_MIN,\r
512 TCP_MAX_LOSS,\r
513 TCP_MAX_LOSS,\r
514 Option->DataRetries\r
515 );\r
516 Tcb->FinWait2Timeout = TCP_COMP_VAL (\r
517 TCP_FIN_WAIT2_TIME,\r
518 TCP_FIN_WAIT2_TIME_MAX,\r
519 TCP_FIN_WAIT2_TIME,\r
4eb65aff 520 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)\r
8a67d61d 521 );\r
522\r
523 if (Option->TimeWaitTimeout != 0) {\r
524 Tcb->TimeWaitTimeout = TCP_COMP_VAL (\r
525 TCP_TIME_WAIT_TIME,\r
526 TCP_TIME_WAIT_TIME_MAX,\r
527 TCP_TIME_WAIT_TIME,\r
4eb65aff 528 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)\r
8a67d61d 529 );\r
530 } else {\r
531 Tcb->TimeWaitTimeout = 0;\r
532 }\r
533\r
534 if (Option->KeepAliveProbes != 0) {\r
535 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
536\r
537 Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (\r
538 TCP_MAX_KEEPALIVE_MIN,\r
539 TCP_MAX_KEEPALIVE,\r
540 TCP_MAX_KEEPALIVE,\r
541 Option->KeepAliveProbes\r
542 );\r
543 Tcb->KeepAliveIdle = TCP_COMP_VAL (\r
544 TCP_KEEPALIVE_IDLE_MIN,\r
545 TCP_KEEPALIVE_IDLE_MAX,\r
546 TCP_KEEPALIVE_IDLE_MIN,\r
4eb65aff 547 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)\r
8a67d61d 548 );\r
549 Tcb->KeepAlivePeriod = TCP_COMP_VAL (\r
550 TCP_KEEPALIVE_PERIOD_MIN,\r
551 TCP_KEEPALIVE_PERIOD,\r
552 TCP_KEEPALIVE_PERIOD,\r
4eb65aff 553 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)\r
8a67d61d 554 );\r
555 }\r
556\r
557 Tcb->ConnectTimeout = TCP_COMP_VAL (\r
558 TCP_CONNECT_TIME_MIN,\r
559 TCP_CONNECT_TIME,\r
560 TCP_CONNECT_TIME,\r
4eb65aff 561 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)\r
8a67d61d 562 );\r
563\r
e2851998 564 if (!Option->EnableNagle) {\r
8a67d61d 565 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);\r
566 }\r
567\r
e2851998 568 if (!Option->EnableTimeStamp) {\r
8a67d61d 569 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);\r
570 }\r
571\r
e2851998 572 if (!Option->EnableWindowScaling) {\r
8a67d61d 573 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);\r
574 }\r
575 }\r
576\r
e5e12de7 577 //\r
578 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is\r
579 // determined, construct the IP device path and install it.\r
580 //\r
581 Status = TcpInstallDevicePath (Sk);\r
582 if (EFI_ERROR (Status)) {\r
583 goto OnExit;\r
584 }\r
585\r
8a67d61d 586 //\r
587 // update state of Tcb and socket\r
588 //\r
e2851998 589 if (!CfgData->AccessPoint.ActiveFlag) {\r
8a67d61d 590\r
591 TcpSetState (Tcb, TCP_LISTEN);\r
592 SockSetState (Sk, SO_LISTENING);\r
593\r
594 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;\r
595 } else {\r
596\r
597 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;\r
598 }\r
599\r
600 TcpInsertTcb (Tcb);\r
601\r
602OnExit:\r
603\r
604 return Status;\r
605}\r
606\r
607\r
608/**\r
609 The procotol handler provided to the socket layer, used to\r
610 dispatch the socket level requests by calling the corresponding\r
611 TCP layer functions.\r
612\r
613 @param Sock Pointer to the socket of this TCP instance.\r
614 @param Request The code of this operation request.\r
615 @param Data Pointer to the operation specific data passed in\r
616 together with the operation request.\r
617\r
618 @retval EFI_SUCCESS The socket request is completed successfully.\r
619 @retval other The error status returned by the corresponding TCP\r
620 layer function.\r
621\r
622**/\r
623EFI_STATUS\r
624Tcp4Dispatcher (\r
625 IN SOCKET *Sock,\r
f6b7393c 626 IN UINT8 Request,\r
8a67d61d 627 IN VOID *Data OPTIONAL\r
628 )\r
629{\r
630 TCP_CB *Tcb;\r
631 TCP4_PROTO_DATA *ProtoData;\r
632 EFI_IP4_PROTOCOL *Ip;\r
633\r
634 ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
635 Tcb = ProtoData->TcpPcb;\r
636\r
637 switch (Request) {\r
638 case SOCK_POLL:\r
2a2e33b2 639 Ip = ProtoData->TcpService->IpIo->Ip.Ip4;\r
8a67d61d 640 Ip->Poll (Ip);\r
641 break;\r
642\r
643 case SOCK_CONSUMED:\r
644 //\r
645 // After user received data from socket buffer, socket will\r
646 // notify TCP using this message to give it a chance to send out\r
647 // window update information\r
648 //\r
120db52c 649 ASSERT (Tcb != NULL);\r
8a67d61d 650 TcpOnAppConsume (Tcb);\r
651 break;\r
652\r
653 case SOCK_SND:\r
654\r
120db52c 655 ASSERT (Tcb != NULL);\r
8a67d61d 656 TcpOnAppSend (Tcb);\r
657 break;\r
658\r
659 case SOCK_CLOSE:\r
660\r
661 TcpOnAppClose (Tcb);\r
662\r
663 break;\r
664\r
665 case SOCK_ABORT:\r
666\r
667 TcpOnAppAbort (Tcb);\r
668\r
669 break;\r
670\r
671 case SOCK_SNDPUSH:\r
672 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);\r
673 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);\r
674\r
675 break;\r
676\r
677 case SOCK_SNDURG:\r
678 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;\r
679 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r
680\r
681 break;\r
682\r
683 case SOCK_CONNECT:\r
684\r
685 TcpOnAppConnect (Tcb);\r
686\r
687 break;\r
688\r
689 case SOCK_ATTACH:\r
690\r
691 return Tcp4AttachPcb (Sock);\r
692\r
8a67d61d 693 case SOCK_FLUSH:\r
694\r
695 Tcp4FlushPcb (Tcb);\r
696\r
697 break;\r
698\r
699 case SOCK_DETACH:\r
700\r
701 Tcp4DetachPcb (Sock);\r
702\r
703 break;\r
704\r
705 case SOCK_CONFIGURE:\r
706\r
707 return Tcp4ConfigurePcb (\r
708 Sock,\r
709 (EFI_TCP4_CONFIG_DATA *) Data\r
710 );\r
711\r
8a67d61d 712 case SOCK_MODE:\r
713\r
120db52c 714 ASSERT ((Data != NULL) && (Tcb != NULL));\r
8a67d61d 715\r
716 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);\r
717\r
8a67d61d 718 case SOCK_ROUTE:\r
719\r
120db52c 720 ASSERT ((Data != NULL) && (Tcb != NULL));\r
8a67d61d 721\r
722 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);\r
723\r
b61439a7 724 default:\r
725 return EFI_UNSUPPORTED;\r
8a67d61d 726 }\r
727\r
728 return EFI_SUCCESS;\r
729\r
730}\r