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