iPXE
pccrr.c File Reference

Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR]. More...

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/uri.h>
#include <ipxe/open.h>
#include <ipxe/http.h>
#include <ipxe/base16.h>
#include <ipxe/pccrc.h>
#include <ipxe/pccrr.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
static int peerdist_open_post (struct interface *xfer, const char *location, size_t digestsize, const uint8_t *id, unsigned int block)
 Open retrieval protocol connection using HTTP POST.
static int peerdist_open_get (struct interface *xfer, const char *location, size_t digestsize, const uint8_t *id, unsigned int block)
 Open retrieval protocol connection using HTTP GET or local file.

Variables

struct peerdist_retrieval peerdist_post
 PeerDist retrieval protocol using HTTP POST.
struct peerdist_retrieval peerdist_get
 PeerDist retrieval protocol using HTTP GET or local file.

Detailed Description

Peer Content Caching and Retrieval: Retrieval Protocol [MS-PCCRR].

The MS-PCCRR specification defines an HTTP POST request/response pair for retrieving an encrypted block from a peer (with the decryption keys provided separately via the content information).

The HTTP POST request parameters serve only to identify the block: the actual response body is effectively a static encrypted blob.

We define an additional (non-standard) retrieval protocol in which the block is identified solely using the request URI, with the response being the same content that would be returned as the HTTP POST response body. This allows for encrypted blocks to be retrieved from a static source such as AWS S3 or a local FAT filesystem, without requiring a peer that can understand the retrieval protocol HTTP POST request format.

We define the static request URI format as:

<base>/xx/xxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy-b.blk

where

  • xxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy is the segment ID (HoHoDK) as a lower-case hexadecimal string
  • xx is the first two characters (i.e. the first byte) of the segment ID
  • b is the block index within the segment (which will always be zero when using MS-PCCRC version 2 content information), as an unpadded decimal string
  • the extension .blk represents a block file

This path format is designed to allow for efficient storage in a local FAT filesystem (by limiting both the number of directories and the number of entries within each directory).

Definition in file pccrr.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ peerdist_open_post()

int peerdist_open_post ( struct interface * xfer,
const char * location,
size_t digestsize,
const uint8_t * id,
unsigned int block )
static

Open retrieval protocol connection using HTTP POST.

Parameters
xferData transfer interface
locationPeer location
digestsizeDigest size
idSegment identifier
blockBlock index
Return values
rcReturn status code

Definition at line 90 of file pccrr.c.

92 {
93 char uri_string[ 7 /* "http://" */ + strlen ( location ) +
94 sizeof ( PEERDIST_MAGIC_PATH /* includes NUL */ ) ];
96 struct http_request_content content;
97 struct uri *uri;
98 int rc;
99
100 /* Construct block fetch request */
101 memset ( &req, 0, sizeof ( req ) );
103 req.getblks.hdr.type = htonl ( PEERDIST_MSG_GETBLKS_TYPE );
104 req.getblks.hdr.len = htonl ( sizeof ( req ) );
107 memcpy ( req.segment.id, id, digestsize );
108 req.ranges.ranges.count = htonl ( 1 );
109 req.ranges.range[0].first = htonl ( block );
110 req.ranges.range[0].count = htonl ( 1 );
111
112 /* Construct POST request content */
113 memset ( &content, 0, sizeof ( content ) );
114 content.data = &req;
115 content.len = sizeof ( req );
116
117 /* Construct URI string */
118 snprintf ( uri_string, sizeof ( uri_string ),
119 ( "http://%s" PEERDIST_MAGIC_PATH ), location );
120
121 /* Parse URI */
122 uri = parse_uri ( uri_string );
123 if ( ! uri ) {
124 rc = -ENOMEM;
125 goto err_uri;
126 }
127
128 /* Initiate HTTP POST to retrieve block */
129 if ( ( rc = http_open ( xfer, &http_post, uri, NULL,
130 &content ) ) != 0 ) {
131 DBGC ( xfer, "PCCRR %p could not open %s: %s\n",
132 xfer, uri_string, strerror ( rc ) );
133 goto err_open;
134 }
135
136 err_open:
137 uri_put ( uri );
138 err_uri:
139 return rc;
140}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
__be32 raw[7]
Definition CIB_PRM.h:0
struct golan_inbox_hdr hdr
Message header.
Definition CIB_PRM.h:0
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
u32 version
Driver version.
Definition ath9k_hw.c:1985
ring len
Length.
Definition dwmac.h:226
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define DBGC(...)
Definition compiler.h:530
static unsigned int count
Number of entries.
Definition dwmac.h:220
#define ENOMEM
Not enough space.
Definition errno.h:578
int http_open(struct interface *xfer, struct http_method *method, struct uri *uri, struct http_request_range *range, struct http_request_content *content)
Open HTTP transaction.
Definition httpcore.c:665
u16 algorithm
Authentication algorithm (Open System or Shared Key).
Definition ieee80211.h:1
#define htonl(value)
Definition byteswap.h:134
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * memset(void *dest, int character, size_t len) __nonnull
uint16_t segment
Code segment.
Definition librm.h:3
uint8_t block[3][8]
DES-encrypted blocks.
Definition mschapv2.h:1
if(natsemi->flags &NATSEMI_64BIT) return 1
uint32_t first
First block in range.
Definition pccrr.h:1
#define peerdist_msg_getblks_t(digestsize, count, vrf_len)
Retrieval protocol block fetch request.
Definition pccrr.h:268
#define PEERDIST_MAGIC_PATH
Magic retrieval URI path.
Definition pccrr.h:20
#define PEERDIST_MSG_GETBLKS_VERSION
Retrieval protocol block fetch request version.
Definition pccrr.h:277
@ PEERDIST_MSG_AES_128_CBC
AES-128 in CBC mode.
Definition pccrr.h:174
#define PEERDIST_MSG_GETBLKS_TYPE
Retrieval protocol block fetch request type.
Definition pccrr.h:280
uint32_t digestsize
Digest size (i.e.
Definition pccrr.h:1
struct pci_range range
PCI bus:dev.fn address range.
Definition pcicloud.c:40
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
HTTP request content descriptor.
Definition http.h:151
A Uniform Resource Identifier.
Definition uri.h:65
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition uri.c:297
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References block, http_request_content::data, DBGC, digestsize, ENOMEM, htonl, http_open(), http_request_content::len, memcpy(), memset(), NULL, parse_uri(), PEERDIST_MAGIC_PATH, PEERDIST_MSG_AES_128_CBC, peerdist_msg_getblks_t, PEERDIST_MSG_GETBLKS_TYPE, PEERDIST_MSG_GETBLKS_VERSION, rc, snprintf(), strerror(), strlen(), and uri_put().

◆ peerdist_open_get()

int peerdist_open_get ( struct interface * xfer,
const char * location,
size_t digestsize,
const uint8_t * id,
unsigned int block )
static

Open retrieval protocol connection using HTTP GET or local file.

Parameters
xferData transfer interface
locationPeer location
digestsizeDigest size
idSegment identifier
blockBlock index
Return values
rcReturn status code

Definition at line 158 of file pccrr.c.

160 {
161 char uri_string[ strlen ( location ) + 4 /* "/xx/" */ +
162 ( 2 * PEERDIST_DIGEST_MAX_SIZE ) + 1 /* "-" */ +
163 10 /* block number */ + 4 /* ".blk" */ +
164 1 /* NUL */ ];
165 size_t len;
166 int rc;
167
168 /* Construct URI string */
170 len = snprintf ( uri_string, sizeof ( uri_string ), "%s/%02x/",
171 location, id[0] );
172 assert ( len < sizeof ( uri_string ) );
173 len += base16_encode ( id, digestsize, ( uri_string + len ),
174 ( sizeof ( uri_string ) - len ) );
175 assert ( len < sizeof ( uri_string ) );
176 snprintf ( ( uri_string + len ), ( sizeof ( uri_string ) - len ),
177 "-%d.blk", block );
178
179 /* Open URI */
180 if ( ( rc = xfer_open_uri_string ( xfer, uri_string ) ) != 0 ) {
181 DBGC ( xfer, "PCCRR %p could not open %s: %s\n",
182 xfer, uri_string, strerror ( rc ) );
183 return rc;
184 }
185
186 return 0;
187}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
int xfer_open_uri_string(struct interface *intf, const char *uri_string)
Open URI string.
Definition open.c:125
#define PEERDIST_DIGEST_MAX_SIZE
Maximum digest size for any supported algorithm.
Definition pccrc.h:298

References assert, block, DBGC, digestsize, len, PEERDIST_DIGEST_MAX_SIZE, rc, snprintf(), strerror(), strlen(), and xfer_open_uri_string().

Variable Documentation

◆ peerdist_post

struct peerdist_retrieval peerdist_post
Initial value:
= {
.name = "POST",
}
static int peerdist_open_post(struct interface *xfer, const char *location, size_t digestsize, const uint8_t *id, unsigned int block)
Open retrieval protocol connection using HTTP POST.
Definition pccrr.c:90

PeerDist retrieval protocol using HTTP POST.

Definition at line 143 of file pccrr.c.

143 {
144 .name = "POST",
145 .open = peerdist_open_post,
146};

Referenced by peerdisc_create(), and peerdisc_socket_rx().

◆ peerdist_get

struct peerdist_retrieval peerdist_get
Initial value:
= {
.name = "GET",
}
static int peerdist_open_get(struct interface *xfer, const char *location, size_t digestsize, const uint8_t *id, unsigned int block)
Open retrieval protocol connection using HTTP GET or local file.
Definition pccrr.c:158

PeerDist retrieval protocol using HTTP GET or local file.

Definition at line 190 of file pccrr.c.

190 {
191 .name = "GET",
192 .open = peerdist_open_get,
193};

Referenced by peerdisc_create().