Browse Source

[peerdist] Add support for PeerDist (aka BranchCache) HTTP content encoding

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 years ago
parent
commit
fd18417cf1
3 changed files with 149 additions and 0 deletions
  1. 3
    0
      src/config/config_http.c
  2. 1
    0
      src/config/general.h
  3. 145
    0
      src/net/peerdist.c

+ 3
- 0
src/config/config_http.c View File

@@ -40,3 +40,6 @@ REQUIRE_OBJECT ( httpbasic );
40 40
 #ifdef HTTP_AUTH_DIGEST
41 41
 REQUIRE_OBJECT ( httpdigest );
42 42
 #endif
43
+#ifdef HTTP_ENC_PEERDIST
44
+REQUIRE_OBJECT ( peerdist );
45
+#endif

+ 1
- 0
src/config/general.h View File

@@ -75,6 +75,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
75 75
  */
76 76
 #define HTTP_AUTH_BASIC		/* Basic authentication */
77 77
 #define HTTP_AUTH_DIGEST	/* Digest authentication */
78
+//#define HTTP_ENC_PEERDIST	/* PeerDist content encoding */
78 79
 
79 80
 /*
80 81
  * 802.11 cryptosystems and handshaking protocols

+ 145
- 0
src/net/peerdist.c View File

@@ -0,0 +1,145 @@
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
+
24
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
+
26
+#include <stdio.h>
27
+#include <ipxe/http.h>
28
+#include <ipxe/peermux.h>
29
+
30
+/** @file
31
+ *
32
+ * Peer Content Caching and Retrieval (PeerDist) protocol
33
+ *
34
+ * This is quite possibly the ugliest protocol I have ever had the
35
+ * misfortune to encounter, and I've encountered multicast TFTP.
36
+ */
37
+
38
+/**
39
+ * Check whether or not to support PeerDist encoding for this request
40
+ *
41
+ * @v http		HTTP transaction
42
+ * @ret supported	PeerDist encoding is supported for this request
43
+ */
44
+static int http_peerdist_supported ( struct http_transaction *http ) {
45
+
46
+	/* Support PeerDist encoding only if we can directly access an
47
+	 * underlying data transfer buffer.  Direct access is required
48
+	 * in order to support decryption of data received via the
49
+	 * retrieval protocol (which provides the AES initialisation
50
+	 * vector only after all of the encrypted data has been
51
+	 * received).
52
+	 *
53
+	 * This test simultaneously ensures that we do not attempt to
54
+	 * use PeerDist encoding on a request which is itself a
55
+	 * PeerDist individual block download, since the individual
56
+	 * block downloads do not themselves provide direct access to
57
+	 * an underlying data transfer buffer.
58
+	 */
59
+	return ( xfer_buffer ( &http->xfer ) != NULL );
60
+}
61
+
62
+/**
63
+ * Format HTTP "X-P2P-PeerDist" header
64
+ *
65
+ * @v http		HTTP transaction
66
+ * @v buf		Buffer
67
+ * @v len		Length of buffer
68
+ * @ret len		Length of header value, or negative error
69
+ */
70
+static int http_format_p2p_peerdist ( struct http_transaction *http,
71
+				      char *buf, size_t len ) {
72
+	int supported = http_peerdist_supported ( http );
73
+	int missing;
74
+
75
+	/* PeerDist wants us to inform the server whenever we make a
76
+	 * request for data that was missing from local peers
77
+	 * (presumably for statistical purposes only).  We use the
78
+	 * heuristic of assuming that the combination of "this request
79
+	 * may not itself use PeerDist content encoding" and "this is
80
+	 * a range request" probably indicates that we are making a
81
+	 * PeerDist block raw range request for missing data.
82
+	 */
83
+	missing = ( http->request.range.len && ( ! supported ) );
84
+
85
+	/* Omit header if PeerDist encoding is not supported and we
86
+	 * are not reporting a missing data request.
87
+	 */
88
+	if ( ! ( supported || missing ) )
89
+		return 0;
90
+
91
+	/* Construct header */
92
+	return snprintf ( buf, len, "Version=1.1%s",
93
+			  ( missing ? ", MissingDataRequest=true" : "" ) );
94
+}
95
+
96
+/** HTTP "X-P2P-PeerDist" header */
97
+struct http_request_header http_request_p2p_peerdist __http_request_header = {
98
+	.name = "X-P2P-PeerDist",
99
+	.format = http_format_p2p_peerdist,
100
+};
101
+
102
+/**
103
+ * Format HTTP "X-P2P-PeerDistEx" header
104
+ *
105
+ * @v http		HTTP transaction
106
+ * @v buf		Buffer
107
+ * @v len		Length of buffer
108
+ * @ret len		Length of header value, or negative error
109
+ */
110
+static int http_format_p2p_peerdistex ( struct http_transaction *http,
111
+					char *buf, size_t len ) {
112
+	int supported = http_peerdist_supported ( http );
113
+
114
+	/* Omit header if PeerDist encoding is not supported */
115
+	if ( ! supported )
116
+		return 0;
117
+
118
+	/* Construct header */
119
+	return snprintf ( buf, len, ( "MinContentInformation=1.0, "
120
+				      "MaxContentInformation=2.0" ) );
121
+}
122
+
123
+/** HTTP "X-P2P-PeerDist" header */
124
+struct http_request_header http_request_p2p_peerdistex __http_request_header = {
125
+	.name = "X-P2P-PeerDistEx",
126
+	.format = http_format_p2p_peerdistex,
127
+};
128
+
129
+/**
130
+ * Initialise PeerDist content encoding
131
+ *
132
+ * @v http		HTTP transaction
133
+ * @ret rc		Return status code
134
+ */
135
+static int http_peerdist_init ( struct http_transaction *http ) {
136
+
137
+	return peermux_filter ( &http->content, &http->transfer, http->uri );
138
+}
139
+
140
+/** PeerDist HTTP content encoding */
141
+struct http_content_encoding peerdist_encoding __http_content_encoding = {
142
+	.name = "peerdist",
143
+	.supported = http_peerdist_supported,
144
+	.init = http_peerdist_init,
145
+};

Loading…
Cancel
Save