]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Dispatcher.c
sync function header to avoid ecc
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Tcp4Dxe / Tcp4Dispatcher.c
... / ...
CommitLineData
1/** @file\r
2\r
3Copyright (c) 2005 - 2006, Intel Corporation<BR>\r
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
7http://opensource.org/licenses/bsd-license.php<BR>\r
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
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
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
35EFI_STATUS\r
36Tcp4Route (\r
37 IN TCP_CB *Tcb,\r
38 IN TCP4_ROUTE_INFO *RouteInfo\r
39 )\r
40{\r
41 EFI_IP4_PROTOCOL *Ip;\r
42\r
43 Ip = Tcb->IpInfo->Ip;\r
44\r
45 ASSERT (Ip != NULL);\r
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
54 \r
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
70EFI_STATUS\r
71Tcp4GetMode (\r
72 IN TCP_CB *Tcb,\r
73 IN OUT TCP4_MODE_DATA *Mode\r
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
88 if (Mode->Tcp4State != NULL) {\r
89 *(Mode->Tcp4State) = (EFI_TCP4_CONNECTION_STATE) Tcb->State;\r
90 }\r
91\r
92 if (Mode->Tcp4ConfigData != NULL) {\r
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
103 CopyMem (&AccessPoint->StationAddress, &Tcb->LocalEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
104 AccessPoint->SubnetMask = Tcb->SubnetMask;\r
105 AccessPoint->StationPort = NTOHS (Tcb->LocalEnd.Port);\r
106\r
107 CopyMem (&AccessPoint->RemoteAddress, &Tcb->RemoteEnd.Ip, sizeof (EFI_IPv4_ADDRESS));\r
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
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
126 Option->EnableWindowScaling = (BOOLEAN) (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_WS));\r
127\r
128 Option->EnableSelectiveAck = FALSE;\r
129 Option->EnablePathMtuDiscovery = FALSE;\r
130 }\r
131 }\r
132\r
133 Ip = Tcb->IpInfo->Ip;\r
134 ASSERT (Ip != NULL);\r
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
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
186 DEBUG ((EFI_D_ERROR, "Tcp4Bind: no port can be allocated "\r
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
207 Flush the Tcb add its associated protocols.\r
208\r
209 @param Tcb Pointer to the TCP_CB to be flushed.\r
210\r
211**/\r
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
226 RemoveEntryList (&Tcb->List);\r
227\r
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
236 gBS->FreePool (Sock->DevicePath);\r
237\r
238 TcpSetVariableData (TcpProto->TcpService);\r
239 }\r
240\r
241 NetbufFreeList (&Tcb->SndQue);\r
242 NetbufFreeList (&Tcb->RcvQue);\r
243}\r
244\r
245/**\r
246 Attach a Pcb to the socket.\r
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
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
263 Tcb = AllocateZeroPool (sizeof (TCP_CB));\r
264\r
265 if (Tcb == NULL) {\r
266\r
267 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: failed to allocate a TCB\n"));\r
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
281 gBS->FreePool (Tcb);\r
282 return EFI_OUT_OF_RESOURCES;\r
283 }\r
284\r
285 InitializeListHead (&Tcb->List);\r
286 InitializeListHead (&Tcb->SndQue);\r
287 InitializeListHead (&Tcb->RcvQue);\r
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
296/**\r
297 Detach the Pcb of the socket.\r
298\r
299 @param Sk Pointer to the socket of this TCP instance.\r
300 \r
301**/\r
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
319 gBS->FreePool (Tcb);\r
320\r
321 ProtoData->TcpPcb = NULL;\r
322}\r
323\r
324\r
325/**\r
326 Configure the Pcb using CfgData.\r
327\r
328 @param Sk Pointer to the socket of this TCP instance.\r
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
337EFI_STATUS\r
338Tcp4ConfigurePcb (\r
339 IN SOCKET *Sk,\r
340 IN EFI_TCP4_CONFIG_DATA *CfgData\r
341 )\r
342{\r
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
349 ASSERT ((CfgData != NULL) && (Sk != NULL) && (Sk->SockHandle != NULL));\r
350\r
351 TcpProto = (TCP4_PROTO_DATA *) Sk->ProtoReserved;\r
352 Tcb = TcpProto->TcpPcb;\r
353\r
354 ASSERT (Tcb != NULL);\r
355\r
356 //\r
357 // Add Ip for send pkt to the peer\r
358 //\r
359 CopyMem (&IpCfgData, &mIpIoDefaultIpConfigData, sizeof (IpCfgData));\r
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
388 DEBUG ((EFI_D_ERROR, "Tcp4ConfigurePcb: Bind endpoint failed "\r
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
398 IsListEmpty (&Tcb->SndQue) &&\r
399 IsListEmpty (&Tcb->RcvQue));\r
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
429 Tcb->UseDefaultAddr = CfgData->AccessPoint.UseDefaultAddress;\r
430\r
431 CopyMem (&Tcb->LocalEnd.Ip, &CfgData->AccessPoint.StationAddress, sizeof (IP4_ADDR));\r
432 Tcb->LocalEnd.Port = HTONS (CfgData->AccessPoint.StationPort);\r
433 Tcb->SubnetMask = CfgData->AccessPoint.SubnetMask;\r
434\r
435 if (CfgData->AccessPoint.ActiveFlag) {\r
436 CopyMem (&Tcb->RemoteEnd.Ip, &CfgData->AccessPoint.RemoteAddress, sizeof (IP4_ADDR));\r
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
442\r
443 Option = CfgData->ControlOption;\r
444\r
445 if (Option != NULL) {\r
446 SET_RCV_BUFFSIZE (\r
447 Sk,\r
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
455 );\r
456 SET_SND_BUFFSIZE (\r
457 Sk,\r
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
465 );\r
466\r
467 SET_BACKLOG (\r
468 Sk,\r
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
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
488 (UINT32) (Option->FinTimeout * TCP_TICK_HZ)\r
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
496 (UINT32) (Option->TimeWaitTimeout * TCP_TICK_HZ)\r
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
515 (UINT32) (Option->KeepAliveTime * TCP_TICK_HZ)\r
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
521 (UINT32) (Option->KeepAliveInterval * TCP_TICK_HZ)\r
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
529 (UINT32) (Option->ConnectionTimeout * TCP_TICK_HZ)\r
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
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
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
617 ASSERT (Tcb != NULL);\r
618 TcpOnAppConsume (Tcb);\r
619 break;\r
620\r
621 case SOCK_SND:\r
622\r
623 ASSERT (Tcb != NULL);\r
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
686 ASSERT ((Data != NULL) && (Tcb != NULL));\r
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
694 ASSERT ((Data != NULL) && (Tcb != NULL));\r
695\r
696 return Tcp4Route (Tcb, (TCP4_ROUTE_INFO *) Data);\r
697\r
698 default:\r
699 return EFI_UNSUPPORTED;\r
700 }\r
701\r
702 return EFI_SUCCESS;\r
703\r
704}\r