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