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