iPXE
peerdist.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stdio.h>
28#include <ipxe/http.h>
29#include <ipxe/settings.h>
30#include <ipxe/peermux.h>
31
32/** @file
33 *
34 * Peer Content Caching and Retrieval (PeerDist) protocol
35 *
36 * This is quite possibly the ugliest protocol I have ever had the
37 * misfortune to encounter, and I've encountered multicast TFTP.
38 */
39
40/** PeerDist is globally enabled */
41static long peerdist_enabled = 1;
42
43/**
44 * Check whether or not to support PeerDist encoding for this request
45 *
46 * @v http HTTP transaction
47 * @ret supported PeerDist encoding is supported for this request
48 */
49static int http_peerdist_supported ( struct http_transaction *http ) {
50
51 /* Allow PeerDist to be globally enabled/disabled */
52 if ( ! peerdist_enabled )
53 return 0;
54
55 /* Support PeerDist encoding only if we can directly access an
56 * underlying data transfer buffer. Direct access is required
57 * in order to support decryption of data received via the
58 * retrieval protocol (which provides the AES initialisation
59 * vector only after all of the encrypted data has been
60 * received).
61 *
62 * This test simultaneously ensures that we do not attempt to
63 * use PeerDist encoding on a request which is itself a
64 * PeerDist individual block download, since the individual
65 * block downloads do not themselves provide direct access to
66 * an underlying data transfer buffer.
67 */
68 return ( xfer_buffer ( &http->xfer ) != NULL );
69}
70
71/**
72 * Format HTTP "X-P2P-PeerDist" header
73 *
74 * @v http HTTP transaction
75 * @v buf Buffer
76 * @v len Length of buffer
77 * @ret len Length of header value, or negative error
78 */
80 char *buf, size_t len ) {
82 int missing;
83
84 /* PeerDist wants us to inform the server whenever we make a
85 * request for data that was missing from local peers
86 * (presumably for statistical purposes only). We use the
87 * heuristic of assuming that the combination of "this request
88 * may not itself use PeerDist content encoding" and "this is
89 * a range request" probably indicates that we are making a
90 * PeerDist block raw range request for missing data.
91 */
92 missing = ( http->request.range.len && ( ! supported ) );
93
94 /* Omit header if PeerDist encoding is not supported and we
95 * are not reporting a missing data request.
96 */
97 if ( ! ( supported || missing ) )
98 return 0;
99
100 /* Construct header */
101 return snprintf ( buf, len, "Version=1.1%s",
102 ( missing ? ", MissingDataRequest=true" : "" ) );
103}
104
105/** HTTP "X-P2P-PeerDist" header */
106struct http_request_header http_request_p2p_peerdist __http_request_header = {
107 .name = "X-P2P-PeerDist",
108 .format = http_format_p2p_peerdist,
109};
110
111/**
112 * Format HTTP "X-P2P-PeerDistEx" header
113 *
114 * @v http HTTP transaction
115 * @v buf Buffer
116 * @v len Length of buffer
117 * @ret len Length of header value, or negative error
118 */
120 char *buf, size_t len ) {
121 int supported = http_peerdist_supported ( http );
122
123 /* Omit header if PeerDist encoding is not supported */
124 if ( ! supported )
125 return 0;
126
127 /* Construct header */
128 return snprintf ( buf, len, ( "MinContentInformation=1.0, "
129 "MaxContentInformation=2.0" ) );
130}
131
132/** HTTP "X-P2P-PeerDist" header */
133struct http_request_header http_request_p2p_peerdistex __http_request_header = {
134 .name = "X-P2P-PeerDistEx",
136};
137
138/**
139 * Initialise PeerDist content encoding
140 *
141 * @v http HTTP transaction
142 * @ret rc Return status code
143 */
144static int http_peerdist_init ( struct http_transaction *http ) {
145
146 return peermux_filter ( &http->content, &http->transfer, http->uri );
147}
148
149/** PeerDist HTTP content encoding */
151 .name = "peerdist",
152 .supported = http_peerdist_supported,
153 .init = http_peerdist_init,
154};
155
156/** PeerDist enabled setting */
157const struct setting peerdist_setting __setting ( SETTING_MISC, peerdist ) = {
158 .name = "peerdist",
159 .description = "PeerDist enabled",
160 .type = &setting_type_int8,
161};
162
163/**
164 * Apply PeerDist settings
165 *
166 * @ret rc Return status code
167 */
168static int apply_peerdist_settings ( void ) {
169
170 /* Fetch global PeerDist enabled setting */
171 if ( fetch_int_setting ( NULL, &peerdist_setting,
172 &peerdist_enabled ) < 0 ) {
174 }
175 DBGC ( &peerdist_enabled, "PEERDIST is %s\n",
176 ( peerdist_enabled ? "enabled" : "disabled" ) );
177
178 return 0;
179}
180
181/** PeerDist settings applicator */
182struct settings_applicator peerdist_applicator __settings_applicator = {
184};
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
ring len
Length.
Definition dwmac.h:226
uint16_t supported
Bitmask of supported option values.
Definition ena.h:1
#define DBGC(...)
Definition compiler.h:505
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define SETTING_MISC
Miscellaneous settings.
Definition settings.h:81
Hyper Text Transport Protocol.
#define __http_content_encoding
Declare an HTTP content encoding.
Definition http.h:509
#define __http_request_header
Declare an HTTP request header.
Definition http.h:246
Configuration settings.
#define __setting(setting_order, name)
Declare a configuration setting.
Definition settings.h:57
#define __settings_applicator
Declare a settings applicator.
Definition settings.h:265
static int apply_peerdist_settings(void)
Apply PeerDist settings.
Definition peerdist.c:168
static int http_peerdist_supported(struct http_transaction *http)
Check whether or not to support PeerDist encoding for this request.
Definition peerdist.c:49
static int http_peerdist_init(struct http_transaction *http)
Initialise PeerDist content encoding.
Definition peerdist.c:144
static int http_format_p2p_peerdistex(struct http_transaction *http, char *buf, size_t len)
Format HTTP "X-P2P-PeerDistEx" header.
Definition peerdist.c:119
static int http_format_p2p_peerdist(struct http_transaction *http, char *buf, size_t len)
Format HTTP "X-P2P-PeerDist" header.
Definition peerdist.c:79
static long peerdist_enabled
PeerDist is globally enabled.
Definition peerdist.c:41
int peermux_filter(struct interface *xfer, struct interface *info, struct uri *uri)
Add PeerDist content-encoding filter.
Definition peermux.c:413
Peer Content Caching and Retrieval (PeerDist) protocol multiplexer.
int fetch_int_setting(struct settings *settings, const struct setting *setting, long *value)
Fetch value of signed integer setting.
Definition settings.c:1024
An HTTP content encoding.
Definition http.h:487
An HTTP request header.
Definition http.h:227
size_t len
Range length, or zero for no range request.
Definition http.h:140
struct http_request_range range
Range descriptor.
Definition http.h:219
An HTTP transaction.
Definition http.h:416
struct uri * uri
Request URI.
Definition http.h:435
struct interface transfer
Transfer-decoded interface.
Definition http.h:424
struct interface content
Content-decoded interface.
Definition http.h:422
struct http_request request
Request.
Definition http.h:437
struct interface xfer
Data transfer interface.
Definition http.h:420
A setting.
Definition settings.h:24
A settings applicator.
Definition settings.h:252
A data transfer buffer.
Definition xferbuf.h:19
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383