1 /** @file
2   The header files of miscellaneous routines for HttpDxe driver.
3 
4 Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef __EFI_HTTP_PROTO_H__
11 #define __EFI_HTTP_PROTO_H__
12 
13 #define DEF_BUF_LEN                         2048
14 
15 #define HTTP_SERVICE_SIGNATURE  SIGNATURE_32('H', 't', 't', 'S')
16 
17 #define HTTP_SERVICE_FROM_PROTOCOL(a) \
18   CR ( \
19   (a), \
20   HTTP_SERVICE, \
21   ServiceBinding, \
22   HTTP_SERVICE_SIGNATURE \
23   )
24 
25 
26 //
27 // The state of HTTP protocol. It starts from UNCONFIGED.
28 //
29 #define HTTP_STATE_UNCONFIGED        0
30 #define HTTP_STATE_HTTP_CONFIGED     1
31 #define HTTP_STATE_TCP_CONFIGED      2
32 #define HTTP_STATE_TCP_UNCONFIGED    3
33 #define HTTP_STATE_TCP_CONNECTED     4
34 #define HTTP_STATE_TCP_CLOSED        5
35 
36 //
37 // TCP configured data.
38 //
39 #define HTTP_TOS_DEAULT              8
40 #define HTTP_TTL_DEAULT              255
41 #define HTTP_BUFFER_SIZE_DEAULT      65535
42 #define HTTP_MAX_SYN_BACK_LOG        5
43 #define HTTP_CONNECTION_TIMEOUT      60
44 #define HTTP_RESPONSE_TIMEOUT        5
45 #define HTTP_DATA_RETRIES            12
46 #define HTTP_FIN_TIMEOUT             2
47 #define HTTP_KEEP_ALIVE_PROBES       6
48 #define HTTP_KEEP_ALIVE_TIME         7200
49 #define HTTP_KEEP_ALIVE_INTERVAL     30
50 
51 #define HTTP_URL_BUFFER_LEN          4096
52 
53 typedef struct _HTTP_SERVICE {
54   UINT32                        Signature;
55   EFI_SERVICE_BINDING_PROTOCOL  ServiceBinding;
56   EFI_HANDLE                    Ip4DriverBindingHandle;
57   EFI_HANDLE                    Ip6DriverBindingHandle;
58   EFI_HANDLE                    ControllerHandle;
59   EFI_HANDLE                    Tcp4ChildHandle;
60   EFI_HANDLE                    Tcp6ChildHandle;
61   LIST_ENTRY                    ChildrenList;
62   UINTN                         ChildrenNumber;
63   INTN                          State;
64 } HTTP_SERVICE;
65 
66 typedef struct {
67   EFI_TCP4_IO_TOKEN             Tx4Token;
68   EFI_TCP4_TRANSMIT_DATA        Tx4Data;
69   EFI_TCP6_IO_TOKEN             Tx6Token;
70   EFI_TCP6_TRANSMIT_DATA        Tx6Data;
71   EFI_TCP4_IO_TOKEN             Rx4Token;
72   EFI_TCP4_RECEIVE_DATA         Rx4Data;
73   EFI_TCP6_IO_TOKEN             Rx6Token;
74   EFI_TCP6_RECEIVE_DATA         Rx6Data;
75   BOOLEAN                       IsTxDone;
76   BOOLEAN                       IsRxDone;
77   UINTN                         BodyLen;
78   EFI_HTTP_METHOD               Method;
79 } HTTP_TCP_TOKEN_WRAP;
80 
81 typedef struct {
82   EFI_TLS_VERSION               Version;
83   EFI_TLS_CONNECTION_END        ConnectionEnd;
84   EFI_TLS_VERIFY                VerifyMethod;
85   EFI_TLS_VERIFY_HOST           VerifyHost;
86   EFI_TLS_SESSION_STATE         SessionState;
87 } TLS_CONFIG_DATA;
88 
89 //
90 // Callback data for HTTP_PARSER_CALLBACK()
91 //
92 typedef struct {
93   UINTN                         ParseDataLength;
94   VOID                          *ParseData;
95   VOID                          *Wrap;
96 } HTTP_CALLBACK_DATA;
97 
98 typedef struct _HTTP_PROTOCOL {
99   UINT32                        Signature;
100   EFI_HTTP_PROTOCOL             Http;
101   EFI_HANDLE                    Handle;
102   HTTP_SERVICE                  *Service;
103   LIST_ENTRY                    Link;   // Link to all HTTP instance from the service.
104   BOOLEAN                       InDestroy;
105   INTN                          State;
106   EFI_HTTP_METHOD               Method;
107 
108   UINTN                         StatusCode;
109 
110   EFI_EVENT                     TimeoutEvent;
111 
112   EFI_HANDLE                    Tcp4ChildHandle;
113   EFI_TCP4_PROTOCOL             *Tcp4;
114   EFI_TCP4_CONFIG_DATA          Tcp4CfgData;
115   EFI_TCP4_OPTION               Tcp4Option;
116 
117   EFI_TCP4_CONNECTION_TOKEN     Tcp4ConnToken;
118   BOOLEAN                       IsTcp4ConnDone;
119   EFI_TCP4_CLOSE_TOKEN          Tcp4CloseToken;
120   BOOLEAN                       IsTcp4CloseDone;
121   CHAR8                         *RemoteHost;
122   UINT16                        RemotePort;
123   EFI_IPv4_ADDRESS              RemoteAddr;
124 
125   EFI_HANDLE                    Tcp6ChildHandle;
126   EFI_TCP6_PROTOCOL             *Tcp6;
127   EFI_TCP6_CONFIG_DATA          Tcp6CfgData;
128   EFI_TCP6_OPTION               Tcp6Option;
129 
130   EFI_TCP6_CONNECTION_TOKEN     Tcp6ConnToken;
131   BOOLEAN                       IsTcp6ConnDone;
132   EFI_TCP6_CLOSE_TOKEN          Tcp6CloseToken;
133   BOOLEAN                       IsTcp6CloseDone;
134   EFI_IPv6_ADDRESS              RemoteIpv6Addr;
135 
136   //
137   // Rx4Token or Rx6Token used for receiving HTTP header.
138   //
139   EFI_TCP4_IO_TOKEN             Rx4Token;
140   EFI_TCP4_RECEIVE_DATA         Rx4Data;
141   EFI_TCP6_IO_TOKEN             Rx6Token;
142   EFI_TCP6_RECEIVE_DATA         Rx6Data;
143   BOOLEAN                       IsRxDone;
144 
145   CHAR8                         **EndofHeader;
146   CHAR8                         **HttpHeaders;
147   CHAR8                         *CacheBody;
148   CHAR8                         *NextMsg;
149   UINTN                         CacheLen;
150   UINTN                         CacheOffset;
151 
152   //
153   // HTTP message-body parser.
154   //
155   VOID                          *MsgParser;
156   HTTP_CALLBACK_DATA            CallbackData;
157 
158   EFI_HTTP_VERSION              HttpVersion;
159   UINT32                        TimeOutMillisec;
160   BOOLEAN                       LocalAddressIsIPv6;
161 
162   EFI_HTTPv4_ACCESS_POINT       IPv4Node;
163   EFI_HTTPv6_ACCESS_POINT       Ipv6Node;
164 
165   NET_MAP                       TxTokens;
166   NET_MAP                       RxTokens;
167 
168   CHAR8                         *Url;
169 
170   //
171   // Https Support
172   //
173   BOOLEAN                          UseHttps;
174 
175   EFI_SERVICE_BINDING_PROTOCOL     *TlsSb;
176   EFI_HANDLE                       TlsChildHandle; /// Tls ChildHandle
177   TLS_CONFIG_DATA                  TlsConfigData;
178   EFI_TLS_PROTOCOL                 *Tls;
179   EFI_TLS_CONFIGURATION_PROTOCOL   *TlsConfiguration;
180   EFI_TLS_SESSION_STATE            TlsSessionState;
181 
182   //
183   // TlsTxData used for transmitting TLS related messages.
184   //
185   EFI_TCP4_IO_TOKEN                Tcp4TlsTxToken;
186   EFI_TCP4_TRANSMIT_DATA           Tcp4TlsTxData;
187   EFI_TCP6_IO_TOKEN                Tcp6TlsTxToken;
188   EFI_TCP6_TRANSMIT_DATA           Tcp6TlsTxData;
189   BOOLEAN                          TlsIsTxDone;
190 
191   //
192   // TlsRxData used for receiving TLS related messages.
193   //
194   EFI_TCP4_IO_TOKEN                Tcp4TlsRxToken;
195   EFI_TCP4_RECEIVE_DATA            Tcp4TlsRxData;
196   EFI_TCP6_IO_TOKEN                Tcp6TlsRxToken;
197   EFI_TCP6_RECEIVE_DATA            Tcp6TlsRxData;
198   BOOLEAN                          TlsIsRxDone;
199 } HTTP_PROTOCOL;
200 
201 typedef struct {
202   EFI_HTTP_TOKEN                *HttpToken;
203   HTTP_PROTOCOL                 *HttpInstance;
204   HTTP_TCP_TOKEN_WRAP           TcpWrap;
205 } HTTP_TOKEN_WRAP;
206 
207 
208 #define HTTP_PROTOCOL_SIGNATURE  SIGNATURE_32('H', 't', 't', 'P')
209 
210 #define HTTP_INSTANCE_FROM_PROTOCOL(a) \
211   CR ( \
212   (a), \
213   HTTP_PROTOCOL, \
214   Http, \
215   HTTP_PROTOCOL_SIGNATURE \
216   )
217 
218 /**
219   The common notify function used in HTTP driver.
220 
221   @param[in]  Event   The event signaled.
222   @param[in]  Context The context.
223 
224 **/
225 VOID
226 EFIAPI
227 HttpCommonNotify (
228   IN EFI_EVENT  Event,
229   IN VOID       *Context
230   );
231 
232 /**
233   Create events for the TCP connection token and TCP close token.
234 
235   @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
236 
237   @retval EFI_SUCCESS            The events are created successfully.
238   @retval others                 Other error as indicated.
239 
240 **/
241 EFI_STATUS
242 HttpCreateTcpConnCloseEvent (
243   IN  HTTP_PROTOCOL        *HttpInstance
244   );
245 
246 /**
247   Close events in the TCP connection token and TCP close token.
248 
249   @param[in]  HttpInstance   Pointer to HTTP_PROTOCOL structure.
250 
251 **/
252 VOID
253 HttpCloseTcpConnCloseEvent (
254   IN  HTTP_PROTOCOL        *HttpInstance
255   );
256 
257 /**
258   Create event for the TCP transmit token.
259 
260   @param[in]  Wrap               Point to HTTP token's wrap data.
261 
262   @retval EFI_SUCCESS            The events is created successfully.
263   @retval others                 Other error as indicated.
264 
265 **/
266 EFI_STATUS
267 HttpCreateTcpTxEvent (
268   IN  HTTP_TOKEN_WRAP      *Wrap
269   );
270 
271 /**
272   Create event for the TCP receive token which is used to receive HTTP header.
273 
274   @param[in]  HttpInstance       Pointer to HTTP_PROTOCOL structure.
275 
276   @retval EFI_SUCCESS            The events is created successfully.
277   @retval others                 Other error as indicated.
278 
279 **/
280 EFI_STATUS
281 HttpCreateTcpRxEventForHeader (
282   IN  HTTP_PROTOCOL        *HttpInstance
283   );
284 
285 /**
286   Create event for the TCP receive token which is used to receive HTTP body.
287 
288   @param[in]  Wrap               Point to HTTP token's wrap data.
289 
290   @retval EFI_SUCCESS            The events is created successfully.
291   @retval others                 Other error as indicated.
292 
293 **/
294 EFI_STATUS
295 HttpCreateTcpRxEvent (
296   IN  HTTP_TOKEN_WRAP      *Wrap
297   );
298 
299 /**
300   Close Events for Tcp Receive Tokens for HTTP body and HTTP header.
301 
302   @param[in]  Wrap               Pointer to HTTP token's wrap data.
303 
304 **/
305 VOID
306 HttpCloseTcpRxEvent (
307   IN  HTTP_TOKEN_WRAP      *Wrap
308   );
309 
310 /**
311   Initialize the HTTP_PROTOCOL structure to the unconfigured state.
312 
313   @param[in, out]  HttpInstance         Pointer to HTTP_PROTOCOL structure.
314   @param[in]       IpVersion            Indicate us TCP4 protocol or TCP6 protocol.
315 
316   @retval EFI_SUCCESS       HTTP_PROTOCOL structure is initialized successfully.
317   @retval Others            Other error as indicated.
318 
319 **/
320 EFI_STATUS
321 HttpInitProtocol (
322   IN OUT HTTP_PROTOCOL           *HttpInstance,
323   IN     BOOLEAN                 IpVersion
324   );
325 
326 /**
327   Clean up the HTTP child, release all the resources used by it.
328 
329   @param[in]  HttpInstance       The HTTP child to clean up.
330 
331 **/
332 VOID
333 HttpCleanProtocol (
334   IN  HTTP_PROTOCOL          *HttpInstance
335   );
336 
337 /**
338   Establish TCP connection with HTTP server.
339 
340   @param[in]  HttpInstance       The HTTP instance private data.
341 
342   @retval EFI_SUCCESS            The TCP connection is established.
343   @retval Others                 Other error as indicated.
344 
345 **/
346 EFI_STATUS
347 HttpCreateConnection (
348   IN  HTTP_PROTOCOL        *HttpInstance
349   );
350 
351 /**
352   Close existing TCP connection.
353 
354   @param[in]  HttpInstance       The HTTP instance private data.
355 
356   @retval EFI_SUCCESS            The TCP connection is closed.
357   @retval Others                 Other error as indicated.
358 
359 **/
360 EFI_STATUS
361 HttpCloseConnection (
362   IN  HTTP_PROTOCOL        *HttpInstance
363   );
364 
365 /**
366   Configure TCP4 protocol child.
367 
368   @param[in]  HttpInstance       The HTTP instance private data.
369   @param[in]  Wrap               The HTTP token's wrap data.
370 
371   @retval EFI_SUCCESS            The TCP4 protocol child is configured.
372   @retval Others                 Other error as indicated.
373 
374 **/
375 EFI_STATUS
376 HttpConfigureTcp4 (
377   IN  HTTP_PROTOCOL        *HttpInstance,
378   IN  HTTP_TOKEN_WRAP      *Wrap
379   );
380 
381 /**
382   Configure TCP6 protocol child.
383 
384   @param[in]  HttpInstance       The HTTP instance private data.
385   @param[in]  Wrap               The HTTP token's wrap data.
386 
387   @retval EFI_SUCCESS            The TCP6 protocol child is configured.
388   @retval Others                 Other error as indicated.
389 
390 **/
391 EFI_STATUS
392 HttpConfigureTcp6 (
393   IN  HTTP_PROTOCOL        *HttpInstance,
394   IN  HTTP_TOKEN_WRAP      *Wrap
395   );
396 
397 /**
398   Check existing TCP connection, if in error state, recover TCP4 connection. Then,
399   connect one TLS session if required.
400 
401   @param[in]  HttpInstance       The HTTP instance private data.
402 
403   @retval EFI_SUCCESS            The TCP connection is established.
404   @retval EFI_NOT_READY          TCP4 protocol child is not created or configured.
405   @retval Others                 Other error as indicated.
406 
407 **/
408 EFI_STATUS
409 HttpConnectTcp4 (
410   IN  HTTP_PROTOCOL        *HttpInstance
411   );
412 
413 /**
414   Check existing TCP connection, if in error state, recover TCP6 connection. Then,
415   connect one TLS session if required.
416 
417   @param[in]  HttpInstance       The HTTP instance private data.
418 
419   @retval EFI_SUCCESS            The TCP connection is established.
420   @retval EFI_NOT_READY          TCP6 protocol child is not created or configured.
421   @retval Others                 Other error as indicated.
422 
423 **/
424 EFI_STATUS
425 HttpConnectTcp6 (
426   IN  HTTP_PROTOCOL        *HttpInstance
427   );
428 
429 /**
430   Send the HTTP or HTTPS message through TCP4 or TCP6.
431 
432   @param[in]  HttpInstance       The HTTP instance private data.
433   @param[in]  Wrap               The HTTP token's wrap data.
434   @param[in]  TxString           Buffer containing the HTTP message string.
435   @param[in]  TxStringLen        Length of the HTTP message string in bytes.
436 
437   @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit queue.
438   @retval Others                 Other error as indicated.
439 
440 **/
441 EFI_STATUS
442 HttpTransmitTcp (
443   IN  HTTP_PROTOCOL    *HttpInstance,
444   IN  HTTP_TOKEN_WRAP  *Wrap,
445   IN  UINT8            *TxString,
446   IN  UINTN            TxStringLen
447   );
448 
449 /**
450   Check whether the user's token or event has already
451   been enqueue on HTTP Tx or Rx Token list.
452 
453   @param[in]  Map                The container of either user's transmit or receive
454                                  token.
455   @param[in]  Item               Current item to check against.
456   @param[in]  Context            The Token to check against.
457 
458   @retval EFI_ACCESS_DENIED      The token or event has already been enqueued in IP
459   @retval EFI_SUCCESS            The current item isn't the same token/event as the
460                                  context.
461 
462 **/
463 EFI_STATUS
464 EFIAPI
465 HttpTokenExist (
466   IN NET_MAP                *Map,
467   IN NET_MAP_ITEM           *Item,
468   IN VOID                   *Context
469   );
470 
471 /**
472   Check whether the HTTP message associated with TxToken or Tx6Token is already sent out.
473 
474   @param[in]  Map                The container of TxToken.
475   @param[in]  Item               Current item to check against.
476   @param[in]  Context            The Token to check against.
477 
478   @retval EFI_NOT_READY          The HTTP message is still queued in the list.
479   @retval EFI_SUCCESS            The HTTP message has been sent out.
480 
481 **/
482 EFI_STATUS
483 EFIAPI
484 HttpTcpNotReady (
485   IN NET_MAP                *Map,
486   IN NET_MAP_ITEM           *Item,
487   IN VOID                   *Context
488   );
489 
490 /**
491   Initialize Http session.
492 
493   @param[in]  HttpInstance       The HTTP instance private data.
494   @param[in]  Wrap               The HTTP token's wrap data.
495   @param[in]  Configure          The Flag indicates whether need to initialize session.
496   @param[in]  TlsConfigure       The Flag indicates whether it's the new Tls session.
497 
498   @retval EFI_SUCCESS            The initialization of session is done.
499   @retval Others                 Other error as indicated.
500 
501 **/
502 EFI_STATUS
503 HttpInitSession (
504   IN  HTTP_PROTOCOL    *HttpInstance,
505   IN  HTTP_TOKEN_WRAP  *Wrap,
506   IN  BOOLEAN          Configure,
507   IN  BOOLEAN          TlsConfigure
508   );
509 
510 /**
511   Transmit the HTTP or HTTPS message by processing the associated HTTP token.
512 
513   @param[in]  Map                The container of TxToken or Tx6Token.
514   @param[in]  Item               Current item to check against.
515   @param[in]  Context            The Token to check against.
516 
517   @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
518   @retval EFI_SUCCESS            The HTTP message is queued into TCP transmit
519                                  queue.
520 
521 **/
522 EFI_STATUS
523 EFIAPI
524 HttpTcpTransmit (
525   IN NET_MAP                *Map,
526   IN NET_MAP_ITEM           *Item,
527   IN VOID                   *Context
528   );
529 
530 /**
531   Receive the HTTP response by processing the associated HTTP token.
532 
533   @param[in]  Map                The container of Rx4Token or Rx6Token.
534   @param[in]  Item               Current item to check against.
535   @param[in]  Context            The Token to check against.
536 
537   @retval EFI_SUCCESS            The HTTP response is queued into TCP receive
538                                  queue.
539   @retval Others                 Other error as indicated.
540 
541 **/
542 EFI_STATUS
543 EFIAPI
544 HttpTcpReceive (
545   IN NET_MAP                *Map,
546   IN NET_MAP_ITEM           *Item,
547   IN VOID                   *Context
548   );
549 
550 /**
551   Receive the HTTP header by processing the associated HTTP token.
552 
553   @param[in]       HttpInstance    The HTTP instance private data.
554   @param[in, out]  SizeofHeaders   The HTTP header length.
555   @param[in, out]  BufferSize      The size of buffer to cache the header message.
556   @param[in]       Timeout         The time to wait for receiving the header packet.
557 
558   @retval EFI_SUCCESS              The HTTP header is received.
559   @retval Others                   Other errors as indicated.
560 
561 **/
562 EFI_STATUS
563 HttpTcpReceiveHeader (
564   IN  HTTP_PROTOCOL         *HttpInstance,
565   IN  OUT UINTN             *SizeofHeaders,
566   IN  OUT UINTN             *BufferSize,
567   IN  EFI_EVENT             Timeout
568   );
569 
570 /**
571   Receive the HTTP body by processing the associated HTTP token.
572 
573   @param[in]  Wrap               The HTTP token's wrap data.
574   @param[in]  HttpMsg            The HTTP message data.
575 
576   @retval EFI_SUCCESS            The HTTP body is received.
577   @retval Others                 Other error as indicated.
578 
579 **/
580 EFI_STATUS
581 HttpTcpReceiveBody (
582   IN  HTTP_TOKEN_WRAP       *Wrap,
583   IN  EFI_HTTP_MESSAGE      *HttpMsg
584   );
585 
586 /**
587   Clean up Tcp Tokens while the Tcp transmission error occurs.
588 
589   @param[in]  Wrap               Pointer to HTTP token's wrap data.
590 
591 **/
592 VOID
593 HttpTcpTokenCleanup (
594   IN  HTTP_TOKEN_WRAP      *Wrap
595   );
596 
597 /**
598   The work function of EfiHttpResponse().
599 
600   @param[in]  Wrap                Pointer to HTTP token's wrap data.
601 
602   @retval EFI_SUCCESS             Allocation succeeded.
603   @retval EFI_OUT_OF_RESOURCES    Failed to complete the operation due to lack of resources.
604   @retval EFI_NOT_READY           Can't find a corresponding TxToken.
605 
606 **/
607 EFI_STATUS
608 HttpResponseWorker (
609   IN  HTTP_TOKEN_WRAP           *Wrap
610   );
611 
612 #endif
613