These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / net / udp / slam.c
1 /*
2  * Copyright (C) 2008 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 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 <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <strings.h>
30 #include <errno.h>
31 #include <assert.h>
32 #include <byteswap.h>
33 #include <ipxe/features.h>
34 #include <ipxe/iobuf.h>
35 #include <ipxe/bitmap.h>
36 #include <ipxe/xfer.h>
37 #include <ipxe/open.h>
38 #include <ipxe/uri.h>
39 #include <ipxe/tcpip.h>
40 #include <ipxe/timer.h>
41 #include <ipxe/retry.h>
42
43 /** @file
44  *
45  * Scalable Local Area Multicast protocol
46  *
47  * The SLAM protocol is supported only by Etherboot; it was designed
48  * and implemented by Eric Biederman.  A server implementation is
49  * available in contrib/mini-slamd.  There does not appear to be any
50  * documentation beyond a few sparse comments in Etherboot's
51  * proto_slam.c.
52  *
53  * SLAM packets use three types of data field:
54  *
55  *  Nul : A single NUL (0) byte, used as a list terminator
56  *
57  *  Raw : A block of raw data
58  *
59  *  Int : A variable-length integer, in big-endian order.  The length
60  *        of the integer is encoded in the most significant three bits.
61  *
62  * Packets received by the client have the following layout:
63  *
64  *  Int : Transaction identifier.  This is an opaque value.
65  *
66  *  Int : Total number of bytes in the transfer.
67  *
68  *  Int : Block size, in bytes.
69  *
70  *  Int : Packet sequence number within the transfer (if this packet
71  *        contains data).
72  *
73  *  Raw : Packet data (if this packet contains data).
74  *
75  * Packets transmitted by the client consist of a run-length-encoded
76  * representation of the received-blocks bitmap, looking something
77  * like:
78  *
79  *  Int : Number of consecutive successfully-received packets
80  *  Int : Number of consecutive missing packets
81  *  Int : Number of consecutive successfully-received packets
82  *  Int : Number of consecutive missing packets
83  *  ....
84  *  Nul
85  *
86  */
87
88 FEATURE ( FEATURE_PROTOCOL, "SLAM", DHCP_EB_FEATURE_SLAM, 1 );
89
90 /** Default SLAM server port */
91 #define SLAM_DEFAULT_PORT 10000
92
93 /** Default SLAM multicast IP address */
94 #define SLAM_DEFAULT_MULTICAST_IP \
95         ( ( 239 << 24 ) | ( 255 << 16 ) | ( 1 << 8 ) | ( 1 << 0 ) )
96
97 /** Default SLAM multicast port */
98 #define SLAM_DEFAULT_MULTICAST_PORT 10000
99
100 /** Maximum SLAM header length */
101 #define SLAM_MAX_HEADER_LEN ( 7 /* transaction id */ + 7 /* total_bytes */ + \
102                               7 /* block_size */ )
103
104 /** Maximum number of blocks to request per NACK
105  *
106  * This is a policy decision equivalent to selecting a TCP window
107  * size.
108  */
109 #define SLAM_MAX_BLOCKS_PER_NACK 4
110
111 /** Maximum SLAM NACK length
112  *
113  * We only ever send a NACK for a single range of up to @c
114  * SLAM_MAX_BLOCKS_PER_NACK blocks.
115  */
116 #define SLAM_MAX_NACK_LEN ( 7 /* block */ + 7 /* #blocks */ + 1 /* NUL */ )
117
118 /** SLAM slave timeout */
119 #define SLAM_SLAVE_TIMEOUT ( 1 * TICKS_PER_SEC )
120
121 /** A SLAM request */
122 struct slam_request {
123         /** Reference counter */
124         struct refcnt refcnt;
125
126         /** Data transfer interface */
127         struct interface xfer;
128         /** Unicast socket */
129         struct interface socket;
130         /** Multicast socket */
131         struct interface mc_socket;
132
133         /** Master client retry timer */
134         struct retry_timer master_timer;
135         /** Slave client retry timer */
136         struct retry_timer slave_timer;
137
138         /** Cached header */
139         uint8_t header[SLAM_MAX_HEADER_LEN];
140         /** Size of cached header */
141         size_t header_len;
142         /** Total number of bytes in transfer */
143         unsigned long total_bytes;
144         /** Transfer block size */
145         unsigned long block_size;
146         /** Number of blocks in transfer */
147         unsigned long num_blocks;
148         /** Block bitmap */
149         struct bitmap bitmap;
150         /** NACK sent flag */
151         int nack_sent;
152 };
153
154 /**
155  * Free a SLAM request
156  *
157  * @v refcnt            Reference counter
158  */
159 static void slam_free ( struct refcnt *refcnt ) {
160         struct slam_request *slam =
161                 container_of ( refcnt, struct slam_request, refcnt );
162
163         bitmap_free ( &slam->bitmap );
164         free ( slam );
165 }
166
167 /**
168  * Mark SLAM request as complete
169  *
170  * @v slam              SLAM request
171  * @v rc                Return status code
172  */
173 static void slam_finished ( struct slam_request *slam, int rc ) {
174         static const uint8_t slam_disconnect[] = { 0 };
175
176         DBGC ( slam, "SLAM %p finished with status code %d (%s)\n",
177                slam, rc, strerror ( rc ) );
178
179         /* Send a disconnect message if we ever sent anything to the
180          * server.
181          */
182         if ( slam->nack_sent ) {
183                 xfer_deliver_raw ( &slam->socket, slam_disconnect,
184                                    sizeof ( slam_disconnect ) );
185         }
186
187         /* Stop the retry timers */
188         stop_timer ( &slam->master_timer );
189         stop_timer ( &slam->slave_timer );
190
191         /* Close all data transfer interfaces */
192         intf_shutdown ( &slam->socket, rc );
193         intf_shutdown ( &slam->mc_socket, rc );
194         intf_shutdown ( &slam->xfer, rc );
195 }
196
197 /****************************************************************************
198  *
199  * TX datapath
200  *
201  */
202
203 /**
204  * Add a variable-length value to a SLAM packet
205  *
206  * @v slam              SLAM request
207  * @v iobuf             I/O buffer
208  * @v value             Value to add
209  * @ret rc              Return status code
210  *
211  * Adds a variable-length value to the end of an I/O buffer.  Will
212  * always leave at least one byte of tailroom in the I/O buffer (to
213  * allow space for the terminating NUL).
214  */
215 static int slam_put_value ( struct slam_request *slam,
216                             struct io_buffer *iobuf, unsigned long value ) {
217         uint8_t *data;
218         size_t len;
219         unsigned int i;
220
221         /* Calculate variable length required to store value.  Always
222          * leave at least one byte in the I/O buffer.
223          */
224         len = ( ( flsl ( value ) + 10 ) / 8 );
225         if ( len >= iob_tailroom ( iobuf ) ) {
226                 DBGC2 ( slam, "SLAM %p cannot add %zd-byte value\n",
227                         slam, len );
228                 return -ENOBUFS;
229         }
230         /* There is no valid way within the protocol that we can end
231          * up trying to push a full-sized long (i.e. without space for
232          * the length encoding).
233          */
234         assert ( len <= sizeof ( value ) );
235
236         /* Add value */
237         data = iob_put ( iobuf, len );
238         for ( i = len ; i-- ; ) {
239                 data[i] = value;
240                 value >>= 8;
241         }
242         *data |= ( len << 5 );
243         assert ( value == 0 );
244
245         return 0;
246 }
247
248 /**
249  * Send SLAM NACK packet
250  *
251  * @v slam              SLAM request
252  * @ret rc              Return status code
253  */
254 static int slam_tx_nack ( struct slam_request *slam ) {
255         struct io_buffer *iobuf;
256         unsigned long first_block;
257         unsigned long num_blocks;
258         uint8_t *nul;
259         int rc;
260
261         /* Mark NACK as sent, so that we know we have to disconnect later */
262         slam->nack_sent = 1;
263
264         /* Allocate I/O buffer */
265         iobuf = xfer_alloc_iob ( &slam->socket, SLAM_MAX_NACK_LEN );
266         if ( ! iobuf ) {
267                 DBGC ( slam, "SLAM %p could not allocate I/O buffer\n",
268                        slam );
269                 return -ENOMEM;
270         }
271
272         /* Construct NACK.  We always request only a single packet;
273          * this allows us to force multicast-TFTP-style flow control
274          * on the SLAM server, which will otherwise just blast the
275          * data out as fast as it can.  On a gigabit network, without
276          * RX checksumming, this would inevitably cause packet drops.
277          */
278         first_block = bitmap_first_gap ( &slam->bitmap );
279         for ( num_blocks = 1 ; ; num_blocks++ ) {
280                 if ( num_blocks >= SLAM_MAX_BLOCKS_PER_NACK )
281                         break;
282                 if ( ( first_block + num_blocks ) >= slam->num_blocks )
283                         break;
284                 if ( bitmap_test ( &slam->bitmap,
285                                    ( first_block + num_blocks ) ) )
286                         break;
287         }
288         if ( first_block ) {
289                 DBGCP ( slam, "SLAM %p transmitting NACK for blocks "
290                         "%ld-%ld\n", slam, first_block,
291                         ( first_block + num_blocks - 1 ) );
292         } else {
293                 DBGC ( slam, "SLAM %p transmitting initial NACK for blocks "
294                        "0-%ld\n", slam, ( num_blocks - 1 ) );
295         }
296         if ( ( rc = slam_put_value ( slam, iobuf, first_block ) ) != 0 )
297                 return rc;
298         if ( ( rc = slam_put_value ( slam, iobuf, num_blocks ) ) != 0 )
299                 return rc;
300         nul = iob_put ( iobuf, 1 );
301         *nul = 0;
302
303         /* Transmit packet */
304         return xfer_deliver_iob ( &slam->socket, iobuf );
305 }
306
307 /**
308  * Handle SLAM master client retry timer expiry
309  *
310  * @v timer             Master retry timer
311  * @v fail              Failure indicator
312  */
313 static void slam_master_timer_expired ( struct retry_timer *timer,
314                                         int fail ) {
315         struct slam_request *slam =
316                 container_of ( timer, struct slam_request, master_timer );
317
318         if ( fail ) {
319                 /* Allow timer to stop running.  We will terminate the
320                  * connection only if the slave timer times out.
321                  */
322                 DBGC ( slam, "SLAM %p giving up acting as master client\n",
323                        slam );
324         } else {
325                 /* Retransmit NACK */
326                 start_timer ( timer );
327                 slam_tx_nack ( slam );
328         }
329 }
330
331 /**
332  * Handle SLAM slave client retry timer expiry
333  *
334  * @v timer             Master retry timer
335  * @v fail              Failure indicator
336  */
337 static void slam_slave_timer_expired ( struct retry_timer *timer,
338                                         int fail ) {
339         struct slam_request *slam =
340                 container_of ( timer, struct slam_request, slave_timer );
341
342         if ( fail ) {
343                 /* Terminate connection */
344                 slam_finished ( slam, -ETIMEDOUT );
345         } else {
346                 /* Try sending a NACK */
347                 DBGC ( slam, "SLAM %p trying to become master client\n",
348                        slam );
349                 start_timer ( timer );
350                 slam_tx_nack ( slam );
351         }
352 }
353
354 /****************************************************************************
355  *
356  * RX datapath
357  *
358  */
359
360 /**
361  * Read and strip a variable-length value from a SLAM packet
362  *
363  * @v slam              SLAM request
364  * @v iobuf             I/O buffer
365  * @v value             Value to fill in, or NULL to ignore value
366  * @ret rc              Return status code
367  *
368  * Reads a variable-length value from the start of the I/O buffer.  
369  */
370 static int slam_pull_value ( struct slam_request *slam,
371                              struct io_buffer *iobuf,
372                              unsigned long *value ) {
373         uint8_t *data;
374         size_t len;
375
376         /* Sanity check */
377         if ( iob_len ( iobuf ) == 0 ) {
378                 DBGC ( slam, "SLAM %p empty value\n", slam );
379                 return -EINVAL;
380         }
381
382         /* Read and verify length of value */
383         data = iobuf->data;
384         len = ( *data >> 5 );
385         if ( ( len == 0 ) ||
386              ( value && ( len > sizeof ( *value ) ) ) ) {
387                 DBGC ( slam, "SLAM %p invalid value length %zd bytes\n",
388                        slam, len );
389                 return -EINVAL;
390         }
391         if ( len > iob_len ( iobuf ) ) {
392                 DBGC ( slam, "SLAM %p value extends beyond I/O buffer\n",
393                        slam );
394                 return -EINVAL;
395         }
396
397         /* Read value */
398         iob_pull ( iobuf, len );
399         *value = ( *data & 0x1f );
400         while ( --len ) {
401                 *value <<= 8;
402                 *value |= *(++data);
403         }
404
405         return 0;
406 }
407
408 /**
409  * Read and strip SLAM header
410  *
411  * @v slam              SLAM request
412  * @v iobuf             I/O buffer
413  * @ret rc              Return status code
414  */
415 static int slam_pull_header ( struct slam_request *slam,
416                               struct io_buffer *iobuf ) {
417         void *header = iobuf->data;
418         int rc;
419
420         /* If header matches cached header, just pull it and return */
421         if ( ( slam->header_len <= iob_len ( iobuf ) ) &&
422              ( memcmp ( slam->header, iobuf->data, slam->header_len ) == 0 )){
423                 iob_pull ( iobuf, slam->header_len );
424                 return 0;
425         }
426
427         DBGC ( slam, "SLAM %p detected changed header; resetting\n", slam );
428
429         /* Read and strip transaction ID, total number of bytes, and
430          * block size.
431          */
432         if ( ( rc = slam_pull_value ( slam, iobuf, NULL ) ) != 0 )
433                 return rc;
434         if ( ( rc = slam_pull_value ( slam, iobuf,
435                                       &slam->total_bytes ) ) != 0 )
436                 return rc;
437         if ( ( rc = slam_pull_value ( slam, iobuf,
438                                       &slam->block_size ) ) != 0 )
439                 return rc;
440
441         /* Update the cached header */
442         slam->header_len = ( iobuf->data - header );
443         assert ( slam->header_len <= sizeof ( slam->header ) );
444         memcpy ( slam->header, header, slam->header_len );
445
446         /* Calculate number of blocks */
447         slam->num_blocks = ( ( slam->total_bytes + slam->block_size - 1 ) /
448                              slam->block_size );
449
450         DBGC ( slam, "SLAM %p has total bytes %ld, block size %ld, num "
451                "blocks %ld\n", slam, slam->total_bytes, slam->block_size,
452                slam->num_blocks );
453
454         /* Discard and reset the bitmap */
455         bitmap_free ( &slam->bitmap );
456         memset ( &slam->bitmap, 0, sizeof ( slam->bitmap ) );
457
458         /* Allocate a new bitmap */
459         if ( ( rc = bitmap_resize ( &slam->bitmap,
460                                     slam->num_blocks ) ) != 0 ) {
461                 /* Failure to allocate a bitmap is fatal */
462                 DBGC ( slam, "SLAM %p could not allocate bitmap for %ld "
463                        "blocks: %s\n", slam, slam->num_blocks,
464                        strerror ( rc ) );
465                 slam_finished ( slam, rc );
466                 return rc;
467         }
468
469         /* Notify recipient of file size */
470         xfer_seek ( &slam->xfer, slam->total_bytes );
471
472         return 0;
473 }
474
475 /**
476  * Receive SLAM data packet
477  *
478  * @v slam              SLAM request
479  * @v iobuf             I/O buffer
480  * @ret rc              Return status code
481  */
482 static int slam_mc_socket_deliver ( struct slam_request *slam,
483                                     struct io_buffer *iobuf,
484                                     struct xfer_metadata *rx_meta __unused ) {
485         struct xfer_metadata meta;
486         unsigned long packet;
487         size_t len;
488         int rc;
489
490         /* Stop the master client timer.  Restart the slave client timer. */
491         stop_timer ( &slam->master_timer );
492         stop_timer ( &slam->slave_timer );
493         start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT );
494
495         /* Read and strip packet header */
496         if ( ( rc = slam_pull_header ( slam, iobuf ) ) != 0 )
497                 goto err_discard;
498
499         /* Read and strip packet number */
500         if ( ( rc = slam_pull_value ( slam, iobuf, &packet ) ) != 0 )
501                 goto err_discard;
502
503         /* Sanity check packet number */
504         if ( packet >= slam->num_blocks ) {
505                 DBGC ( slam, "SLAM %p received out-of-range packet %ld "
506                        "(num_blocks=%ld)\n", slam, packet, slam->num_blocks );
507                 rc = -EINVAL;
508                 goto err_discard;
509         }
510
511         /* Sanity check length */
512         len = iob_len ( iobuf );
513         if ( len > slam->block_size ) {
514                 DBGC ( slam, "SLAM %p received oversize packet of %zd bytes "
515                        "(block_size=%ld)\n", slam, len, slam->block_size );
516                 rc = -EINVAL;
517                 goto err_discard;
518         }
519         if ( ( packet != ( slam->num_blocks - 1 ) ) &&
520              ( len < slam->block_size ) ) {
521                 DBGC ( slam, "SLAM %p received short packet of %zd bytes "
522                        "(block_size=%ld)\n", slam, len, slam->block_size );
523                 rc = -EINVAL;
524                 goto err_discard;
525         }
526
527         /* If we have already seen this packet, discard it */
528         if ( bitmap_test ( &slam->bitmap, packet ) ) {
529                 goto discard;
530         }
531
532         /* Pass to recipient */
533         memset ( &meta, 0, sizeof ( meta ) );
534         meta.flags = XFER_FL_ABS_OFFSET;
535         meta.offset = ( packet * slam->block_size );
536         if ( ( rc = xfer_deliver ( &slam->xfer, iobuf, &meta ) ) != 0 )
537                 goto err;
538
539         /* Mark block as received */
540         bitmap_set ( &slam->bitmap, packet );
541
542         /* If we have received all blocks, terminate */
543         if ( bitmap_full ( &slam->bitmap ) )
544                 slam_finished ( slam, 0 );
545
546         return 0;
547
548  err_discard:
549  discard:
550         free_iob ( iobuf );
551  err:
552         return rc;
553 }
554
555 /**
556  * Receive SLAM non-data packet
557  *
558  * @v slam              SLAM request
559  * @v iobuf             I/O buffer
560  * @ret rc              Return status code
561  */
562 static int slam_socket_deliver ( struct slam_request *slam,
563                                  struct io_buffer *iobuf,
564                                  struct xfer_metadata *rx_meta __unused ) {
565         int rc;
566
567         /* Restart the master client timer */
568         stop_timer ( &slam->master_timer );
569         start_timer ( &slam->master_timer );
570
571         /* Read and strip packet header */
572         if ( ( rc = slam_pull_header ( slam, iobuf ) ) != 0 )
573                 goto discard;
574
575         /* Sanity check */
576         if ( iob_len ( iobuf ) != 0 ) {
577                 DBGC ( slam, "SLAM %p received trailing garbage:\n", slam );
578                 DBGC_HD ( slam, iobuf->data, iob_len ( iobuf ) );
579                 rc = -EINVAL;
580                 goto discard;
581         }
582
583         /* Discard packet */
584         free_iob ( iobuf );
585
586         /* Send NACK in reply */
587         slam_tx_nack ( slam );
588
589         return 0;
590
591  discard:
592         free_iob ( iobuf );
593         return rc;
594
595 }
596
597 /** SLAM unicast socket interface operations */
598 static struct interface_operation slam_socket_operations[] = {
599         INTF_OP ( xfer_deliver, struct slam_request *, slam_socket_deliver ),
600         INTF_OP ( intf_close, struct slam_request *, slam_finished ),
601 };
602
603 /** SLAM unicast socket interface descriptor */
604 static struct interface_descriptor slam_socket_desc =
605         INTF_DESC ( struct slam_request, socket, slam_socket_operations );
606
607 /** SLAM multicast socket interface operations */
608 static struct interface_operation slam_mc_socket_operations[] = {
609         INTF_OP ( xfer_deliver, struct slam_request *, slam_mc_socket_deliver ),
610         INTF_OP ( intf_close, struct slam_request *, slam_finished ),
611 };
612
613 /** SLAM multicast socket interface descriptor */
614 static struct interface_descriptor slam_mc_socket_desc =
615         INTF_DESC ( struct slam_request, mc_socket, slam_mc_socket_operations );
616
617 /****************************************************************************
618  *
619  * Data transfer interface
620  *
621  */
622
623 /** SLAM data transfer interface operations */
624 static struct interface_operation slam_xfer_operations[] = {
625         INTF_OP ( intf_close, struct slam_request *, slam_finished ),
626 };
627
628 /** SLAM data transfer interface descriptor */
629 static struct interface_descriptor slam_xfer_desc =
630         INTF_DESC ( struct slam_request, xfer, slam_xfer_operations );
631
632 /**
633  * Parse SLAM URI multicast address
634  *
635  * @v slam              SLAM request
636  * @v path              Path portion of x-slam:// URI
637  * @v address           Socket address to fill in
638  * @ret rc              Return status code
639  */
640 static int slam_parse_multicast_address ( struct slam_request *slam,
641                                           const char *path,
642                                           struct sockaddr_in *address ) {
643         char path_dup[ strlen ( path ) /* no +1 */ ];
644         char *sep;
645         char *end;
646
647         /* Create temporary copy of path, minus the leading '/' */
648         assert ( *path == '/' );
649         memcpy ( path_dup, ( path + 1 ) , sizeof ( path_dup ) );
650
651         /* Parse port, if present */
652         sep = strchr ( path_dup, ':' );
653         if ( sep ) {
654                 *(sep++) = '\0';
655                 address->sin_port = htons ( strtoul ( sep, &end, 0 ) );
656                 if ( *end != '\0' ) {
657                         DBGC ( slam, "SLAM %p invalid multicast port "
658                                "\"%s\"\n", slam, sep );
659                         return -EINVAL;
660                 }
661         }
662
663         /* Parse address */
664         if ( inet_aton ( path_dup, &address->sin_addr ) == 0 ) {
665                 DBGC ( slam, "SLAM %p invalid multicast address \"%s\"\n",
666                        slam, path_dup );
667                 return -EINVAL;
668         }
669
670         return 0;
671 }
672
673 /**
674  * Initiate a SLAM request
675  *
676  * @v xfer              Data transfer interface
677  * @v uri               Uniform Resource Identifier
678  * @ret rc              Return status code
679  */
680 static int slam_open ( struct interface *xfer, struct uri *uri ) {
681         static const struct sockaddr_in default_multicast = {
682                 .sin_family = AF_INET,
683                 .sin_port = htons ( SLAM_DEFAULT_MULTICAST_PORT ),
684                 .sin_addr = { htonl ( SLAM_DEFAULT_MULTICAST_IP ) },
685         };
686         struct slam_request *slam;
687         struct sockaddr_tcpip server;
688         struct sockaddr_in multicast;
689         int rc;
690
691         /* Sanity checks */
692         if ( ! uri->host )
693                 return -EINVAL;
694
695         /* Allocate and populate structure */
696         slam = zalloc ( sizeof ( *slam ) );
697         if ( ! slam )
698                 return -ENOMEM;
699         ref_init ( &slam->refcnt, slam_free );
700         intf_init ( &slam->xfer, &slam_xfer_desc, &slam->refcnt );
701         intf_init ( &slam->socket, &slam_socket_desc, &slam->refcnt );
702         intf_init ( &slam->mc_socket, &slam_mc_socket_desc, &slam->refcnt );
703         timer_init ( &slam->master_timer, slam_master_timer_expired,
704                      &slam->refcnt );
705         timer_init ( &slam->slave_timer, slam_slave_timer_expired,
706                      &slam->refcnt );
707         /* Fake an invalid cached header of { 0x00, ... } */
708         slam->header_len = 1;
709         /* Fake parameters for initial NACK */
710         slam->num_blocks = 1;
711         if ( ( rc = bitmap_resize ( &slam->bitmap, 1 ) ) != 0 ) {
712                 DBGC ( slam, "SLAM %p could not allocate initial bitmap: "
713                        "%s\n", slam, strerror ( rc ) );
714                 goto err;
715         }
716
717         /* Open unicast socket */
718         memset ( &server, 0, sizeof ( server ) );
719         server.st_port = htons ( uri_port ( uri, SLAM_DEFAULT_PORT ) );
720         if ( ( rc = xfer_open_named_socket ( &slam->socket, SOCK_DGRAM,
721                                              ( struct sockaddr * ) &server,
722                                              uri->host, NULL ) ) != 0 ) {
723                 DBGC ( slam, "SLAM %p could not open unicast socket: %s\n",
724                        slam, strerror ( rc ) );
725                 goto err;
726         }
727
728         /* Open multicast socket */
729         memcpy ( &multicast, &default_multicast, sizeof ( multicast ) );
730         if ( uri->path &&
731              ( ( rc = slam_parse_multicast_address ( slam, uri->path,
732                                                      &multicast ) ) != 0 ) ) {
733                 goto err;
734         }
735         if ( ( rc = xfer_open_socket ( &slam->mc_socket, SOCK_DGRAM,
736                                  ( struct sockaddr * ) &multicast,
737                                  ( struct sockaddr * ) &multicast ) ) != 0 ) {
738                 DBGC ( slam, "SLAM %p could not open multicast socket: %s\n",
739                        slam, strerror ( rc ) );
740                 goto err;
741         }
742
743         /* Start slave retry timer */
744         start_timer_fixed ( &slam->slave_timer, SLAM_SLAVE_TIMEOUT );
745
746         /* Attach to parent interface, mortalise self, and return */
747         intf_plug_plug ( &slam->xfer, xfer );
748         ref_put ( &slam->refcnt );
749         return 0;
750
751  err:
752         slam_finished ( slam, rc );
753         ref_put ( &slam->refcnt );
754         return rc;
755 }
756
757 /** SLAM URI opener */
758 struct uri_opener slam_uri_opener __uri_opener = {
759         .scheme = "x-slam",
760         .open   = slam_open,
761 };