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