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