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