]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Dispatcher.c
... / ...
CommitLineData
1/** @file\r
2 Tcp request dispatcher implementation.\r
3\r
4(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
5Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
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
9http://opensource.org/licenses/bsd-license.php<BR>\r
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
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
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
37EFI_STATUS\r
38Tcp4Route (\r
39 IN TCP_CB *Tcb,\r
40 IN TCP4_ROUTE_INFO *RouteInfo\r
41 )\r
42{\r
43 EFI_IP4_PROTOCOL *Ip4;\r
44\r
45 Ip4 = Tcb->IpInfo->Ip.Ip4;\r
46\r
47 ASSERT (Ip4 != NULL);\r
48\r
49 return Ip4->Routes (\r
50 Ip4,\r
51 RouteInfo->DeleteRoute,\r
52 RouteInfo->SubnetAddress,\r
53 RouteInfo->SubnetMask,\r
54 RouteInfo->GatewayAddress\r
55 );\r
56\r
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
72EFI_STATUS\r
73Tcp4GetMode (\r
74 IN TCP_CB *Tcb,\r
75 IN OUT TCP4_MODE_DATA *Mode\r
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
90 if (Mode->Tcp4State != NULL) {\r
91 *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State;\r
92 }\r
93\r
94 if (Mode->Tcp4ConfigData != NULL) {\r
95\r
96 ConfigData = Mode->Tcp4ConfigData;\r
97 AccessPoint = &(ConfigData->AccessPoint);\r
98 Option = ConfigData->ControlOption;\r
99\r
100 ConfigData->TypeOfService = Tcb->Tos;\r
101 ConfigData->TimeToLive = Tcb->Ttl;\r
102\r
103 AccessPoint->UseDefaultAddress = Tcb->UseDefaultAddr;\r
104\r
105 IP4_COPY_ADDRESS (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip);\r
106 IP4_COPY_ADDRESS (&AccessPoint->SubnetMask, &Tcb->SubnetMask);\r
107 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r
108\r
109 IP4_COPY_ADDRESS (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip);\r
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
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
128 Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));\r
129\r
130 Option->EnableSelectiveAck = FALSE;\r
131 Option->EnablePathMtuDiscovery = FALSE;\r
132 }\r
133 }\r
134\r
135 Ip = Tcb->IpInfo->Ip.Ip4;\r
136 ASSERT (Ip != NULL);\r
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
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
188 DEBUG ((EFI_D_ERROR, "Tcp4Bind: no port can be allocated "\r
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
209 Flush the Tcb add its associated protocols.\r
210\r
211 @param Tcb Pointer to the TCP_CB to be flushed.\r
212\r
213**/\r
214VOID\r
215Tcp4FlushPcb (\r
216 IN TCP_CB *Tcb\r
217 )\r
218{\r
219 SOCKET *Sock;\r
220\r
221 IpIoConfigIp (Tcb->IpInfo, NULL);\r
222\r
223 Sock = Tcb->Sk;\r
224\r
225 if (SOCK_IS_CONFIGURED (Sock)) {\r
226 RemoveEntryList (&Tcb->List);\r
227\r
228 //\r
229 // Uninstall the device path protocol.\r
230 //\r
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
239 }\r
240\r
241 NetbufFreeList (&Tcb->SndQue);\r
242 NetbufFreeList (&Tcb->RcvQue);\r
243 Tcb->State = TCP_CLOSED;\r
244}\r
245\r
246/**\r
247 Attach a Pcb to the socket.\r
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
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 EFI_STATUS Status;\r
264 VOID *Ip;\r
265\r
266 Tcb = AllocateZeroPool (sizeof (TCP_CB));\r
267\r
268 if (Tcb == NULL) {\r
269\r
270 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));\r
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
284 FreePool (Tcb);\r
285 return EFI_OUT_OF_RESOURCES;\r
286 }\r
287\r
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
304 InitializeListHead (&Tcb->List);\r
305 InitializeListHead (&Tcb->SndQue);\r
306 InitializeListHead (&Tcb->RcvQue);\r
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
315/**\r
316 Detach the Pcb of the socket.\r
317\r
318 @param Sk Pointer to the socket of this TCP instance.\r
319\r
320**/\r
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
336 IpIoRemoveIp (ProtoData->TcpService->IpIo, Tcb->IpInfo);\r
337\r
338 FreePool (Tcb);\r
339\r
340 ProtoData->TcpPcb = NULL;\r
341}\r
342\r
343\r
344/**\r
345 Configure the Pcb using CfgData.\r
346\r
347 @param Sk Pointer to the socket of this TCP instance.\r
348 @param CfgData Pointer to the TCP configuration data.\r
349\r
350 @retval EFI_SUCCESS The operation is completed successfully.\r
351 @retval EFI_INVALID_PARAMETER A same access point has been configured in\r
352 another TCP instance.\r
353 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.\r
354\r
355**/\r
356EFI_STATUS\r
357Tcp4ConfigurePcb (\r
358 IN SOCKET *Sk,\r
359 IN EFI_TCP4_CONFIG_DATA *CfgData\r
360 )\r
361{\r
362 EFI_IP4_CONFIG_DATA IpCfgData;\r
363 EFI_STATUS Status;\r
364 EFI_TCP4_OPTION *Option;\r
365 TCP4_PROTO_DATA *TcpProto;\r
366 TCP_CB *Tcb;\r
367\r
368 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));\r
369\r
370 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
371 Tcb = TcpProto->TcpPcb;\r
372\r
373 ASSERT (Tcb != NULL);\r
374\r
375 //\r
376 // Add Ip for send pkt to the peer\r
377 //\r
378 CopyMem (&IpCfgData, &mIp4IoDefaultIpConfigData, sizeof (IpCfgData));\r
379 IpCfgData.DefaultProtocol = EFI_IP_PROTO_TCP;\r
380 IpCfgData.UseDefaultAddress = CfgData->AccessPoint.UseDefaultAddress;\r
381 IpCfgData.StationAddress = CfgData->AccessPoint.StationAddress;\r
382 IpCfgData.SubnetMask = CfgData->AccessPoint.SubnetMask;\r
383 IpCfgData.ReceiveTimeout = (UINT32) (-1);\r
384\r
385 //\r
386 // Configure the IP instance this Tcb consumes.\r
387 //\r
388 Status = IpIoConfigIp (Tcb->IpInfo, &IpCfgData);\r
389 if (EFI_ERROR (Status)) {\r
390 goto OnExit;\r
391 }\r
392\r
393 //\r
394 // Get the default address info if the instance is configured to use default address.\r
395 //\r
396 if (CfgData->AccessPoint.UseDefaultAddress) {\r
397 CfgData->AccessPoint.StationAddress = IpCfgData.StationAddress;\r
398 CfgData->AccessPoint.SubnetMask = IpCfgData.SubnetMask;\r
399 }\r
400\r
401 //\r
402 // check if we can bind this endpoint in CfgData\r
403 //\r
404 Status = Tcp4Bind (&(CfgData->AccessPoint));\r
405\r
406 if (EFI_ERROR (Status)) {\r
407 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "\r
408 "with %r\n", Status));\r
409\r
410 goto OnExit;\r
411 }\r
412\r
413 //\r
414 // Initalize the operating information in this Tcb\r
415 //\r
416 ASSERT (Tcb->State == TCP_CLOSED &&\r
417 IsListEmpty (&Tcb->SndQue) &&\r
418 IsListEmpty (&Tcb->RcvQue));\r
419\r
420 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
421 Tcb->State = TCP_CLOSED;\r
422\r
423 Tcb->SndMss = 536;\r
424 Tcb->RcvMss = TcpGetRcvMss (Sk);\r
425\r
426 Tcb->SRtt = 0;\r
427 Tcb->Rto = 3 * TCP_TICK_HZ;\r
428\r
429 Tcb->CWnd = Tcb->SndMss;\r
430 Tcb->Ssthresh = 0xffffffff;\r
431\r
432 Tcb->CongestState = TCP_CONGEST_OPEN;\r
433\r
434 Tcb->KeepAliveIdle = TCP_KEEPALIVE_IDLE_MIN;\r
435 Tcb->KeepAlivePeriod = TCP_KEEPALIVE_PERIOD;\r
436 Tcb->MaxKeepAlive = TCP_MAX_KEEPALIVE;\r
437 Tcb->MaxRexmit = TCP_MAX_LOSS;\r
438 Tcb->FinWait2Timeout = TCP_FIN_WAIT2_TIME;\r
439 Tcb->TimeWaitTimeout = TCP_TIME_WAIT_TIME;\r
440 Tcb->ConnectTimeout = TCP_CONNECT_TIME;\r
441\r
442 //\r
443 // initialize Tcb in the light of CfgData\r
444 //\r
445 Tcb->Ttl = CfgData->TimeToLive;\r
446 Tcb->Tos = CfgData->TypeOfService;\r
447\r
448 Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;\r
449\r
450 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));\r
451 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);\r
452 IP4_COPY_ADDRESS (&Tcb->SubnetMask, &CfgData->AccessPoint.SubnetMask);\r
453\r
454 if (CfgData->AccessPoint.ActiveFlag) {\r
455 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r
456 Tcb->RemoteEnd.Port = HTONS (CfgData->AccessPoint.RemotePort);\r
457 } else {\r
458 Tcb->RemoteEnd.Ip = 0;\r
459 Tcb->RemoteEnd.Port = 0;\r
460 }\r
461\r
462 Option = CfgData->ControlOption;\r
463\r
464 if (Option != NULL) {\r
465 SET_RCV_BUFFSIZE (\r
466 Sk,\r
467 (UINT32) (TCP_COMP_VAL (\r
468 TCP_RCV_BUF_SIZE_MIN,\r
469 TCP_RCV_BUF_SIZE,\r
470 TCP_RCV_BUF_SIZE,\r
471 Option->ReceiveBufferSize\r
472 )\r
473 )\r
474 );\r
475 SET_SND_BUFFSIZE (\r
476 Sk,\r
477 (UINT32) (TCP_COMP_VAL (\r
478 TCP_SND_BUF_SIZE_MIN,\r
479 TCP_SND_BUF_SIZE,\r
480 TCP_SND_BUF_SIZE,\r
481 Option->SendBufferSize\r
482 )\r
483 )\r
484 );\r
485\r
486 SET_BACKLOG (\r
487 Sk,\r
488 (UINT32) (TCP_COMP_VAL (\r
489 TCP_BACKLOG_MIN,\r
490 TCP_BACKLOG,\r
491 TCP_BACKLOG,\r
492 Option->MaxSynBackLog\r
493 )\r
494 )\r
495 );\r
496\r
497 Tcb->MaxRexmit = (UINT16) TCP_COMP_VAL (\r
498 TCP_MAX_LOSS_MIN,\r
499 TCP_MAX_LOSS,\r
500 TCP_MAX_LOSS,\r
501 Option->DataRetries\r
502 );\r
503 Tcb->FinWait2Timeout = TCP_COMP_VAL (\r
504 TCP_FIN_WAIT2_TIME,\r
505 TCP_FIN_WAIT2_TIME_MAX,\r
506 TCP_FIN_WAIT2_TIME,\r
507 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)\r
508 );\r
509\r
510 if (Option->TimeWaitTimeout != 0) {\r
511 Tcb->TimeWaitTimeout = TCP_COMP_VAL (\r
512 TCP_TIME_WAIT_TIME,\r
513 TCP_TIME_WAIT_TIME_MAX,\r
514 TCP_TIME_WAIT_TIME,\r
515 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)\r
516 );\r
517 } else {\r
518 Tcb->TimeWaitTimeout = 0;\r
519 }\r
520\r
521 if (Option->KeepAliveProbes != 0) {\r
522 TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE);\r
523\r
524 Tcb->MaxKeepAlive = (UINT8) TCP_COMP_VAL (\r
525 TCP_MAX_KEEPALIVE_MIN,\r
526 TCP_MAX_KEEPALIVE,\r
527 TCP_MAX_KEEPALIVE,\r
528 Option->KeepAliveProbes\r
529 );\r
530 Tcb->KeepAliveIdle = TCP_COMP_VAL (\r
531 TCP_KEEPALIVE_IDLE_MIN,\r
532 TCP_KEEPALIVE_IDLE_MAX,\r
533 TCP_KEEPALIVE_IDLE_MIN,\r
534 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)\r
535 );\r
536 Tcb->KeepAlivePeriod = TCP_COMP_VAL (\r
537 TCP_KEEPALIVE_PERIOD_MIN,\r
538 TCP_KEEPALIVE_PERIOD,\r
539 TCP_KEEPALIVE_PERIOD,\r
540 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)\r
541 );\r
542 }\r
543\r
544 Tcb->ConnectTimeout = TCP_COMP_VAL (\r
545 TCP_CONNECT_TIME_MIN,\r
546 TCP_CONNECT_TIME,\r
547 TCP_CONNECT_TIME,\r
548 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)\r
549 );\r
550\r
551 if (!Option->EnableNagle) {\r
552 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_NAGLE);\r
553 }\r
554\r
555 if (!Option->EnableTimeStamp) {\r
556 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_TS);\r
557 }\r
558\r
559 if (!Option->EnableWindowScaling) {\r
560 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_NO_WS);\r
561 }\r
562 }\r
563\r
564 //\r
565 // The socket is bound, the <SrcIp, SrcPort, DstIp, DstPort> is\r
566 // determined, construct the IP device path and install it.\r
567 //\r
568 Status = TcpInstallDevicePath (Sk);\r
569 if (EFI_ERROR (Status)) {\r
570 goto OnExit;\r
571 }\r
572\r
573 //\r
574 // update state of Tcb and socket\r
575 //\r
576 if (!CfgData->AccessPoint.ActiveFlag) {\r
577\r
578 TcpSetState (Tcb, TCP_LISTEN);\r
579 SockSetState (Sk, SO_LISTENING);\r
580\r
581 Sk->ConfigureState = SO_CONFIGURED_PASSIVE;\r
582 } else {\r
583\r
584 Sk->ConfigureState = SO_CONFIGURED_ACTIVE;\r
585 }\r
586\r
587 TcpInsertTcb (Tcb);\r
588\r
589OnExit:\r
590\r
591 return Status;\r
592}\r
593\r
594\r
595/**\r
596 The procotol handler provided to the socket layer, used to\r
597 dispatch the socket level requests by calling the corresponding\r
598 TCP layer functions.\r
599\r
600 @param Sock Pointer to the socket of this TCP instance.\r
601 @param Request The code of this operation request.\r
602 @param Data Pointer to the operation specific data passed in\r
603 together with the operation request.\r
604\r
605 @retval EFI_SUCCESS The socket request is completed successfully.\r
606 @retval other The error status returned by the corresponding TCP\r
607 layer function.\r
608\r
609**/\r
610EFI_STATUS\r
611Tcp4Dispatcher (\r
612 IN SOCKET *Sock,\r
613 IN UINT8 Request,\r
614 IN VOID *Data OPTIONAL\r
615 )\r
616{\r
617 TCP_CB *Tcb;\r
618 TCP4_PROTO_DATA *ProtoData;\r
619 EFI_IP4_PROTOCOL *Ip;\r
620\r
621 ProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved;\r
622 Tcb = ProtoData->TcpPcb;\r
623\r
624 switch (Request) {\r
625 case SOCK_POLL:\r
626 Ip = ProtoData->TcpService->IpIo->Ip.Ip4;\r
627 Ip->Poll (Ip);\r
628 break;\r
629\r
630 case SOCK_CONSUMED:\r
631 //\r
632 // After user received data from socket buffer, socket will\r
633 // notify TCP using this message to give it a chance to send out\r
634 // window update information\r
635 //\r
636 ASSERT (Tcb != NULL);\r
637 TcpOnAppConsume (Tcb);\r
638 break;\r
639\r
640 case SOCK_SND:\r
641\r
642 ASSERT (Tcb != NULL);\r
643 TcpOnAppSend (Tcb);\r
644 break;\r
645\r
646 case SOCK_CLOSE:\r
647\r
648 TcpOnAppClose (Tcb);\r
649\r
650 break;\r
651\r
652 case SOCK_ABORT:\r
653\r
654 TcpOnAppAbort (Tcb);\r
655\r
656 break;\r
657\r
658 case SOCK_SNDPUSH:\r
659 Tcb->SndPsh = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk);\r
660 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_PSH);\r
661\r
662 break;\r
663\r
664 case SOCK_SNDURG:\r
665 Tcb->SndUp = TcpGetMaxSndNxt (Tcb) + GET_SND_DATASIZE (Tcb->Sk) - 1;\r
666 TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_SND_URG);\r
667\r
668 break;\r
669\r
670 case SOCK_CONNECT:\r
671\r
672 TcpOnAppConnect (Tcb);\r
673\r
674 break;\r
675\r
676 case SOCK_ATTACH:\r
677\r
678 return Tcp4AttachPcb (Sock);\r
679\r
680 case SOCK_FLUSH:\r
681\r
682 Tcp4FlushPcb (Tcb);\r
683\r
684 break;\r
685\r
686 case SOCK_DETACH:\r
687\r
688 Tcp4DetachPcb (Sock);\r
689\r
690 break;\r
691\r
692 case SOCK_CONFIGURE:\r
693\r
694 return Tcp4ConfigurePcb (\r
695 Sock,\r
696 (EFI_TCP4_CONFIG_DATA *) Data\r
697 );\r
698\r
699 case SOCK_MODE:\r
700\r
701 ASSERT ((Data != NULL) && (Tcb != NULL));\r
702\r
703 return Tcp4GetMode (Tcb, (TCP4_MODE_DATA *) Data);\r
704\r
705 case SOCK_ROUTE:\r
706\r
707 ASSERT ((Data != NULL) && (Tcb != NULL));\r
708\r
709 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);\r
710\r
711 default:\r
712 return EFI_UNSUPPORTED;\r
713 }\r
714\r
715 return EFI_SUCCESS;\r
716\r
717}\r