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