include/boost/corosio/socket_option.hpp

95.9% Lines (71/74) 100.0% List of functions (36/36)
socket_option.hpp
f(x) Functions (36)
Function Calls Lines Blocks
boost::corosio::socket_option::boolean_option::boolean_option(bool) :55 261x 100.0% 100.0% boost::corosio::socket_option::boolean_option::operator=(bool) :58 4x 100.0% 100.0% boost::corosio::socket_option::boolean_option::value() const :65 42x 100.0% 100.0% boost::corosio::socket_option::boolean_option::operator bool() const :71 4x 100.0% 100.0% boost::corosio::socket_option::boolean_option::operator!() const :77 4x 100.0% 100.0% boost::corosio::socket_option::boolean_option::data() :83 44x 100.0% 100.0% boost::corosio::socket_option::boolean_option::data() const :89 261x 100.0% 100.0% boost::corosio::socket_option::boolean_option::size() const :95 305x 100.0% 100.0% boost::corosio::socket_option::boolean_option::resize(unsigned long) :106 44x 75.0% 33.0% boost::corosio::socket_option::integer_option::integer_option(int) :130 24x 100.0% 100.0% boost::corosio::socket_option::integer_option::operator=(int) :133 2x 100.0% 100.0% boost::corosio::socket_option::integer_option::value() const :140 30x 100.0% 100.0% boost::corosio::socket_option::integer_option::data() :146 28x 100.0% 100.0% boost::corosio::socket_option::integer_option::data() const :152 24x 100.0% 100.0% boost::corosio::socket_option::integer_option::size() const :158 52x 100.0% 100.0% boost::corosio::socket_option::integer_option::resize(unsigned long) :167 28x 60.0% 67.0% boost::corosio::socket_option::byte_boolean_option::byte_boolean_option(bool) :194 6x 100.0% 100.0% boost::corosio::socket_option::byte_boolean_option::value() const :204 4x 100.0% 100.0% boost::corosio::socket_option::byte_boolean_option::data() :222 4x 100.0% 100.0% boost::corosio::socket_option::byte_boolean_option::data() const :228 6x 100.0% 100.0% boost::corosio::socket_option::byte_boolean_option::size() const :234 10x 100.0% 100.0% boost::corosio::socket_option::byte_boolean_option::resize(unsigned long) :240 4x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::byte_integer_option(int) :261 2x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::value() const :273 2x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::data() :279 2x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::data() const :285 2x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::size() const :291 4x 100.0% 100.0% boost::corosio::socket_option::byte_integer_option::resize(unsigned long) :297 2x 100.0% 100.0% boost::corosio::socket_option::linger::data() :533 10x 100.0% 100.0% boost::corosio::socket_option::linger::data() const :539 34x 100.0% 100.0% boost::corosio::socket_option::linger::resize(unsigned long) :553 10x 100.0% 100.0% boost::corosio::socket_option::join_group_v4::data() const :701 4x 100.0% 100.0% boost::corosio::socket_option::leave_group_v4::data() const :751 2x 100.0% 100.0% boost::corosio::socket_option::join_group_v6::data() const :800 2x 100.0% 100.0% boost::corosio::socket_option::leave_group_v6::data() const :849 2x 100.0% 100.0% boost::corosio::socket_option::multicast_interface_v4::data() const :900 2x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_SOCKET_OPTION_HPP
11 #define BOOST_COROSIO_SOCKET_OPTION_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14 #include <boost/corosio/ipv4_address.hpp>
15 #include <boost/corosio/ipv6_address.hpp>
16
17 #include <cstddef>
18
19 /** @file socket_option.hpp
20
21 Type-erased socket option types that avoid platform-specific
22 headers. The protocol level and option name for each type are
23 resolved at link time via the compiled library.
24
25 For an inline (zero-overhead) alternative that includes platform
26 headers, use `<boost/corosio/native/native_socket_option.hpp>`
27 (`boost::corosio::native_socket_option`).
28
29 Both variants satisfy the same option-type interface and work
30 interchangeably with `tcp_socket::set_option` /
31 `tcp_socket::get_option` and the corresponding acceptor methods.
32
33 @see native_socket_option
34 */
35
36 namespace boost::corosio::socket_option {
37
38 /** Base class for concrete boolean socket options.
39
40 Stores a boolean as an `int` suitable for `setsockopt`/`getsockopt`.
41 Derived types provide `level()` and `name()` for the specific option.
42 */
43 class boolean_option
44 {
45 int value_ = 0;
46
47 public:
48 /// Construct with default value (disabled).
49 boolean_option() = default;
50
51 /** Construct with an explicit value.
52
53 @param v `true` to enable the option, `false` to disable.
54 */
55 261x explicit boolean_option(bool v) noexcept : value_(v ? 1 : 0) {}
56
57 /// Assign a new value.
58 4x boolean_option& operator=(bool v) noexcept
59 {
60 4x value_ = v ? 1 : 0;
61 4x return *this;
62 }
63
64 /// Return the option value.
65 42x bool value() const noexcept
66 {
67 42x return value_ != 0;
68 }
69
70 /// Return the option value.
71 4x explicit operator bool() const noexcept
72 {
73 4x return value_ != 0;
74 }
75
76 /// Return the negated option value.
77 4x bool operator!() const noexcept
78 {
79 4x return value_ == 0;
80 }
81
82 /// Return a pointer to the underlying storage.
83 44x void* data() noexcept
84 {
85 44x return &value_;
86 }
87
88 /// Return a pointer to the underlying storage.
89 261x void const* data() const noexcept
90 {
91 261x return &value_;
92 }
93
94 /// Return the size of the underlying storage.
95 305x std::size_t size() const noexcept
96 {
97 305x return sizeof(value_);
98 }
99
100 /** Normalize after `getsockopt` returns fewer bytes than expected.
101
102 Windows Vista+ may write only 1 byte for boolean options.
103
104 @param s The number of bytes actually written by `getsockopt`.
105 */
106 44x void resize(std::size_t s) noexcept
107 {
108 44x if (s == sizeof(char))
109 value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
110 44x }
111 };
112
113 /** Base class for concrete integer socket options.
114
115 Stores an integer suitable for `setsockopt`/`getsockopt`.
116 Derived types provide `level()` and `name()` for the specific option.
117 */
118 class integer_option
119 {
120 int value_ = 0;
121
122 public:
123 /// Construct with default value (zero).
124 integer_option() = default;
125
126 /** Construct with an explicit value.
127
128 @param v The option value.
129 */
130 24x explicit integer_option(int v) noexcept : value_(v) {}
131
132 /// Assign a new value.
133 2x integer_option& operator=(int v) noexcept
134 {
135 2x value_ = v;
136 2x return *this;
137 }
138
139 /// Return the option value.
140 30x int value() const noexcept
141 {
142 30x return value_;
143 }
144
145 /// Return a pointer to the underlying storage.
146 28x void* data() noexcept
147 {
148 28x return &value_;
149 }
150
151 /// Return a pointer to the underlying storage.
152 24x void const* data() const noexcept
153 {
154 24x return &value_;
155 }
156
157 /// Return the size of the underlying storage.
158 52x std::size_t size() const noexcept
159 {
160 52x return sizeof(value_);
161 }
162
163 /** Normalize after `getsockopt` returns fewer bytes than expected.
164
165 @param s The number of bytes actually written by `getsockopt`.
166 */
167 28x void resize(std::size_t s) noexcept
168 {
169 28x if (s == sizeof(char))
170 value_ =
171 static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
172 28x }
173 };
174
175 /** Base class for concrete boolean socket options with single-byte storage.
176
177 Some BSD-derived kernels (macOS, FreeBSD) require certain IPv4 multicast
178 options (`IP_MULTICAST_LOOP`) to be set with a one-byte value and return
179 `EINVAL` for the four-byte form that Linux accepts. This base provides
180 `unsigned char` storage so the same options work on every platform.
181 */
182 class byte_boolean_option
183 {
184 unsigned char value_ = 0;
185
186 public:
187 /// Construct with default value (disabled).
188 byte_boolean_option() = default;
189
190 /** Construct with an explicit value.
191
192 @param v `true` to enable the option, `false` to disable.
193 */
194 6x explicit byte_boolean_option(bool v) noexcept : value_(v ? 1 : 0) {}
195
196 /// Assign a new value.
197 byte_boolean_option& operator=(bool v) noexcept
198 {
199 value_ = v ? 1 : 0;
200 return *this;
201 }
202
203 /// Return the option value.
204 4x bool value() const noexcept
205 {
206 4x return value_ != 0;
207 }
208
209 /// Return the option value.
210 explicit operator bool() const noexcept
211 {
212 return value_ != 0;
213 }
214
215 /// Return the negated option value.
216 bool operator!() const noexcept
217 {
218 return value_ == 0;
219 }
220
221 /// Return a pointer to the underlying storage.
222 4x void* data() noexcept
223 {
224 4x return &value_;
225 }
226
227 /// Return a pointer to the underlying storage.
228 6x void const* data() const noexcept
229 {
230 6x return &value_;
231 }
232
233 /// Return the size of the underlying storage.
234 10x std::size_t size() const noexcept
235 {
236 10x return sizeof(value_);
237 }
238
239 /// Storage is already one byte; no normalization needed.
240 4x void resize(std::size_t) noexcept {}
241 };
242
243 /** Base class for concrete integer socket options with single-byte storage.
244
245 Same rationale as `byte_boolean_option`: BSD-derived kernels require
246 `IP_MULTICAST_TTL` to be set with a one-byte value. Linux accepts
247 one-byte too, so single-byte storage is portable.
248 */
249 class byte_integer_option
250 {
251 unsigned char value_ = 0;
252
253 public:
254 /// Construct with default value (zero).
255 byte_integer_option() = default;
256
257 /** Construct with an explicit value.
258
259 @param v The option value; truncated to one byte.
260 */
261 2x explicit byte_integer_option(int v) noexcept
262 2x : value_(static_cast<unsigned char>(v))
263 2x {}
264
265 /// Assign a new value; truncated to one byte.
266 byte_integer_option& operator=(int v) noexcept
267 {
268 value_ = static_cast<unsigned char>(v);
269 return *this;
270 }
271
272 /// Return the option value.
273 2x int value() const noexcept
274 {
275 2x return value_;
276 }
277
278 /// Return a pointer to the underlying storage.
279 2x void* data() noexcept
280 {
281 2x return &value_;
282 }
283
284 /// Return a pointer to the underlying storage.
285 2x void const* data() const noexcept
286 {
287 2x return &value_;
288 }
289
290 /// Return the size of the underlying storage.
291 4x std::size_t size() const noexcept
292 {
293 4x return sizeof(value_);
294 }
295
296 /// Storage is already one byte; no normalization needed.
297 2x void resize(std::size_t) noexcept {}
298 };
299
300 /** Disable Nagle's algorithm (TCP_NODELAY).
301
302 @par Example
303 @code
304 sock.set_option( socket_option::no_delay( true ) );
305 auto nd = sock.get_option<socket_option::no_delay>();
306 if ( nd.value() )
307 // Nagle's algorithm is disabled
308 @endcode
309 */
310 class BOOST_COROSIO_DECL no_delay : public boolean_option
311 {
312 public:
313 using boolean_option::boolean_option;
314 using boolean_option::operator=;
315
316 /// Return the protocol level.
317 static int level() noexcept;
318
319 /// Return the option name.
320 static int name() noexcept;
321 };
322
323 /** Enable periodic keepalive probes (SO_KEEPALIVE).
324
325 @par Example
326 @code
327 sock.set_option( socket_option::keep_alive( true ) );
328 @endcode
329 */
330 class BOOST_COROSIO_DECL keep_alive : public boolean_option
331 {
332 public:
333 using boolean_option::boolean_option;
334 using boolean_option::operator=;
335
336 /// Return the protocol level.
337 static int level() noexcept;
338
339 /// Return the option name.
340 static int name() noexcept;
341 };
342
343 /** Restrict an IPv6 socket to IPv6 only (IPV6_V6ONLY).
344
345 When enabled, the socket only accepts IPv6 connections.
346 When disabled, the socket accepts both IPv4 and IPv6
347 connections (dual-stack mode).
348
349 @par Example
350 @code
351 sock.set_option( socket_option::v6_only( true ) );
352 @endcode
353 */
354 class BOOST_COROSIO_DECL v6_only : public boolean_option
355 {
356 public:
357 using boolean_option::boolean_option;
358 using boolean_option::operator=;
359
360 /// Return the protocol level.
361 static int level() noexcept;
362
363 /// Return the option name.
364 static int name() noexcept;
365 };
366
367 /** Allow local address reuse (SO_REUSEADDR).
368
369 @par Example
370 @code
371 acc.set_option( socket_option::reuse_address( true ) );
372 @endcode
373 */
374 class BOOST_COROSIO_DECL reuse_address : public boolean_option
375 {
376 public:
377 using boolean_option::boolean_option;
378 using boolean_option::operator=;
379
380 /// Return the protocol level.
381 static int level() noexcept;
382
383 /// Return the option name.
384 static int name() noexcept;
385 };
386
387 /** Allow sending to broadcast addresses (SO_BROADCAST).
388
389 Required for UDP sockets that send to broadcast addresses
390 such as 255.255.255.255. Without this option, `send_to`
391 returns an error.
392
393 @par Example
394 @code
395 udp_socket sock( ioc );
396 sock.open();
397 sock.set_option( socket_option::broadcast( true ) );
398 @endcode
399 */
400 class BOOST_COROSIO_DECL broadcast : public boolean_option
401 {
402 public:
403 using boolean_option::boolean_option;
404 using boolean_option::operator=;
405
406 /// Return the protocol level.
407 static int level() noexcept;
408
409 /// Return the option name.
410 static int name() noexcept;
411 };
412
413 /** Allow multiple sockets to bind to the same port (SO_REUSEPORT).
414
415 Not available on all platforms. On unsupported platforms,
416 `set_option` will return an error.
417
418 @par Example
419 @code
420 acc.open( tcp::v6() );
421 acc.set_option( socket_option::reuse_port( true ) );
422 acc.bind( endpoint( ipv6_address::any(), 8080 ) );
423 acc.listen();
424 @endcode
425 */
426 class BOOST_COROSIO_DECL reuse_port : public boolean_option
427 {
428 public:
429 using boolean_option::boolean_option;
430 using boolean_option::operator=;
431
432 /// Return the protocol level.
433 static int level() noexcept;
434
435 /// Return the option name.
436 static int name() noexcept;
437 };
438
439 /** Set the receive buffer size (SO_RCVBUF).
440
441 @par Example
442 @code
443 sock.set_option( socket_option::receive_buffer_size( 65536 ) );
444 auto opt = sock.get_option<socket_option::receive_buffer_size>();
445 int sz = opt.value();
446 @endcode
447 */
448 class BOOST_COROSIO_DECL receive_buffer_size : public integer_option
449 {
450 public:
451 using integer_option::integer_option;
452 using integer_option::operator=;
453
454 /// Return the protocol level.
455 static int level() noexcept;
456
457 /// Return the option name.
458 static int name() noexcept;
459 };
460
461 /** Set the send buffer size (SO_SNDBUF).
462
463 @par Example
464 @code
465 sock.set_option( socket_option::send_buffer_size( 65536 ) );
466 @endcode
467 */
468 class BOOST_COROSIO_DECL send_buffer_size : public integer_option
469 {
470 public:
471 using integer_option::integer_option;
472 using integer_option::operator=;
473
474 /// Return the protocol level.
475 static int level() noexcept;
476
477 /// Return the option name.
478 static int name() noexcept;
479 };
480
481 /** The SO_LINGER socket option.
482
483 Controls behavior when closing a socket with unsent data.
484 When enabled, `close()` blocks until pending data is sent
485 or the timeout expires.
486
487 @par Example
488 @code
489 sock.set_option( socket_option::linger( true, 5 ) );
490 auto opt = sock.get_option<socket_option::linger>();
491 if ( opt.enabled() )
492 std::cout << "linger timeout: " << opt.timeout() << "s\n";
493 @endcode
494 */
495 class BOOST_COROSIO_DECL linger
496 {
497 // Opaque storage for the platform's struct linger.
498 // POSIX: { int, int } = 8 bytes.
499 // Windows: { u_short, u_short } = 4 bytes.
500 static constexpr std::size_t max_storage_ = 8;
501 alignas(4) unsigned char storage_[max_storage_]{};
502
503 public:
504 /// Construct with default values (disabled, zero timeout).
505 linger() noexcept = default;
506
507 /** Construct with explicit values.
508
509 @param enabled `true` to enable linger behavior on close.
510 @param timeout The linger timeout in seconds.
511 */
512 linger(bool enabled, int timeout) noexcept;
513
514 /// Return whether linger is enabled.
515 bool enabled() const noexcept;
516
517 /// Set whether linger is enabled.
518 void enabled(bool v) noexcept;
519
520 /// Return the linger timeout in seconds.
521 int timeout() const noexcept;
522
523 /// Set the linger timeout in seconds.
524 void timeout(int v) noexcept;
525
526 /// Return the protocol level.
527 static int level() noexcept;
528
529 /// Return the option name.
530 static int name() noexcept;
531
532 /// Return a pointer to the underlying storage.
533 10x void* data() noexcept
534 {
535 10x return storage_;
536 }
537
538 /// Return a pointer to the underlying storage.
539 34x void const* data() const noexcept
540 {
541 34x return storage_;
542 }
543
544 /// Return the size of the underlying storage.
545 std::size_t size() const noexcept;
546
547 /** Normalize after `getsockopt`.
548
549 No-op — `struct linger` is always returned at full size.
550
551 @param s The number of bytes actually written by `getsockopt`.
552 */
553 10x void resize(std::size_t) noexcept {}
554 };
555
556 /** Enable loopback of outgoing multicast on IPv4 (IP_MULTICAST_LOOP).
557
558 Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
559 reject the four-byte form with `EINVAL`. Linux accepts either size.
560
561 @par Example
562 @code
563 sock.set_option( socket_option::multicast_loop_v4( true ) );
564 @endcode
565 */
566 class BOOST_COROSIO_DECL multicast_loop_v4 : public byte_boolean_option
567 {
568 public:
569 using byte_boolean_option::byte_boolean_option;
570 using byte_boolean_option::operator=;
571
572 /// Return the protocol level.
573 static int level() noexcept;
574
575 /// Return the option name.
576 static int name() noexcept;
577 };
578
579 /** Enable loopback of outgoing multicast on IPv6 (IPV6_MULTICAST_LOOP).
580
581 @par Example
582 @code
583 sock.set_option( socket_option::multicast_loop_v6( true ) );
584 @endcode
585 */
586 class BOOST_COROSIO_DECL multicast_loop_v6 : public boolean_option
587 {
588 public:
589 using boolean_option::boolean_option;
590 using boolean_option::operator=;
591
592 /// Return the protocol level.
593 static int level() noexcept;
594
595 /// Return the option name.
596 static int name() noexcept;
597 };
598
599 /** Set the multicast TTL for IPv4 (IP_MULTICAST_TTL).
600
601 Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
602 reject the four-byte form with `EINVAL`. Linux accepts either size.
603 Values are truncated to the 0–255 range.
604
605 @par Example
606 @code
607 sock.set_option( socket_option::multicast_hops_v4( 4 ) );
608 @endcode
609 */
610 class BOOST_COROSIO_DECL multicast_hops_v4 : public byte_integer_option
611 {
612 public:
613 using byte_integer_option::byte_integer_option;
614 using byte_integer_option::operator=;
615
616 /// Return the protocol level.
617 static int level() noexcept;
618
619 /// Return the option name.
620 static int name() noexcept;
621 };
622
623 /** Set the multicast hop limit for IPv6 (IPV6_MULTICAST_HOPS).
624
625 @par Example
626 @code
627 sock.set_option( socket_option::multicast_hops_v6( 4 ) );
628 @endcode
629 */
630 class BOOST_COROSIO_DECL multicast_hops_v6 : public integer_option
631 {
632 public:
633 using integer_option::integer_option;
634 using integer_option::operator=;
635
636 /// Return the protocol level.
637 static int level() noexcept;
638
639 /// Return the option name.
640 static int name() noexcept;
641 };
642
643 /** Set the outgoing interface for IPv6 multicast (IPV6_MULTICAST_IF).
644
645 @par Example
646 @code
647 sock.set_option( socket_option::multicast_interface_v6( 1 ) );
648 @endcode
649 */
650 class BOOST_COROSIO_DECL multicast_interface_v6 : public integer_option
651 {
652 public:
653 using integer_option::integer_option;
654 using integer_option::operator=;
655
656 /// Return the protocol level.
657 static int level() noexcept;
658
659 /// Return the option name.
660 static int name() noexcept;
661 };
662
663 /** Join an IPv4 multicast group (IP_ADD_MEMBERSHIP).
664
665 @par Example
666 @code
667 sock.set_option( socket_option::join_group_v4(
668 ipv4_address( "239.255.0.1" ) ) );
669 @endcode
670 */
671 class BOOST_COROSIO_DECL join_group_v4
672 {
673 static constexpr std::size_t max_storage_ = 8;
674 alignas(4) unsigned char storage_[max_storage_]{};
675
676 public:
677 /// Construct with default values.
678 join_group_v4() noexcept = default;
679
680 /** Construct with a group and optional interface address.
681
682 @param group The multicast group address to join.
683 @param iface The local interface to use (default: any).
684 */
685 join_group_v4(
686 ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
687
688 /// Return the protocol level.
689 static int level() noexcept;
690
691 /// Return the option name.
692 static int name() noexcept;
693
694 /// Return a pointer to the underlying storage.
695 void* data() noexcept
696 {
697 return storage_;
698 }
699
700 /// Return a pointer to the underlying storage.
701 4x void const* data() const noexcept
702 {
703 4x return storage_;
704 }
705
706 /// Return the size of the underlying storage.
707 std::size_t size() const noexcept;
708
709 /// No-op resize.
710 void resize(std::size_t) noexcept {}
711 };
712
713 /** Leave an IPv4 multicast group (IP_DROP_MEMBERSHIP).
714
715 @par Example
716 @code
717 sock.set_option( socket_option::leave_group_v4(
718 ipv4_address( "239.255.0.1" ) ) );
719 @endcode
720 */
721 class BOOST_COROSIO_DECL leave_group_v4
722 {
723 static constexpr std::size_t max_storage_ = 8;
724 alignas(4) unsigned char storage_[max_storage_]{};
725
726 public:
727 /// Construct with default values.
728 leave_group_v4() noexcept = default;
729
730 /** Construct with a group and optional interface address.
731
732 @param group The multicast group address to leave.
733 @param iface The local interface (default: any).
734 */
735 leave_group_v4(
736 ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
737
738 /// Return the protocol level.
739 static int level() noexcept;
740
741 /// Return the option name.
742 static int name() noexcept;
743
744 /// Return a pointer to the underlying storage.
745 void* data() noexcept
746 {
747 return storage_;
748 }
749
750 /// Return a pointer to the underlying storage.
751 2x void const* data() const noexcept
752 {
753 2x return storage_;
754 }
755
756 /// Return the size of the underlying storage.
757 std::size_t size() const noexcept;
758
759 /// No-op resize.
760 void resize(std::size_t) noexcept {}
761 };
762
763 /** Join an IPv6 multicast group (IPV6_JOIN_GROUP).
764
765 @par Example
766 @code
767 sock.set_option( socket_option::join_group_v6(
768 ipv6_address( "ff02::1" ), 0 ) );
769 @endcode
770 */
771 class BOOST_COROSIO_DECL join_group_v6
772 {
773 static constexpr std::size_t max_storage_ = 20;
774 alignas(4) unsigned char storage_[max_storage_]{};
775
776 public:
777 /// Construct with default values.
778 join_group_v6() noexcept = default;
779
780 /** Construct with a group and optional interface index.
781
782 @param group The multicast group address to join.
783 @param if_index The interface index (0 = kernel chooses).
784 */
785 join_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
786
787 /// Return the protocol level.
788 static int level() noexcept;
789
790 /// Return the option name.
791 static int name() noexcept;
792
793 /// Return a pointer to the underlying storage.
794 void* data() noexcept
795 {
796 return storage_;
797 }
798
799 /// Return a pointer to the underlying storage.
800 2x void const* data() const noexcept
801 {
802 2x return storage_;
803 }
804
805 /// Return the size of the underlying storage.
806 std::size_t size() const noexcept;
807
808 /// No-op resize.
809 void resize(std::size_t) noexcept {}
810 };
811
812 /** Leave an IPv6 multicast group (IPV6_LEAVE_GROUP).
813
814 @par Example
815 @code
816 sock.set_option( socket_option::leave_group_v6(
817 ipv6_address( "ff02::1" ), 0 ) );
818 @endcode
819 */
820 class BOOST_COROSIO_DECL leave_group_v6
821 {
822 static constexpr std::size_t max_storage_ = 20;
823 alignas(4) unsigned char storage_[max_storage_]{};
824
825 public:
826 /// Construct with default values.
827 leave_group_v6() noexcept = default;
828
829 /** Construct with a group and optional interface index.
830
831 @param group The multicast group address to leave.
832 @param if_index The interface index (0 = kernel chooses).
833 */
834 leave_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
835
836 /// Return the protocol level.
837 static int level() noexcept;
838
839 /// Return the option name.
840 static int name() noexcept;
841
842 /// Return a pointer to the underlying storage.
843 void* data() noexcept
844 {
845 return storage_;
846 }
847
848 /// Return a pointer to the underlying storage.
849 2x void const* data() const noexcept
850 {
851 2x return storage_;
852 }
853
854 /// Return the size of the underlying storage.
855 std::size_t size() const noexcept;
856
857 /// No-op resize.
858 void resize(std::size_t) noexcept {}
859 };
860
861 /** Set the outgoing interface for IPv4 multicast (IP_MULTICAST_IF).
862
863 Unlike the integer-based `multicast_interface_v6`, this option
864 takes an `ipv4_address` identifying the local interface.
865
866 @par Example
867 @code
868 sock.set_option( socket_option::multicast_interface_v4(
869 ipv4_address( "192.168.1.1" ) ) );
870 @endcode
871 */
872 class BOOST_COROSIO_DECL multicast_interface_v4
873 {
874 static constexpr std::size_t max_storage_ = 4;
875 alignas(4) unsigned char storage_[max_storage_]{};
876
877 public:
878 /// Construct with default values (INADDR_ANY).
879 multicast_interface_v4() noexcept = default;
880
881 /** Construct with an interface address.
882
883 @param iface The local interface address.
884 */
885 explicit multicast_interface_v4(ipv4_address iface) noexcept;
886
887 /// Return the protocol level.
888 static int level() noexcept;
889
890 /// Return the option name.
891 static int name() noexcept;
892
893 /// Return a pointer to the underlying storage.
894 void* data() noexcept
895 {
896 return storage_;
897 }
898
899 /// Return a pointer to the underlying storage.
900 2x void const* data() const noexcept
901 {
902 2x return storage_;
903 }
904
905 /// Return the size of the underlying storage.
906 std::size_t size() const noexcept;
907
908 /// No-op resize.
909 void resize(std::size_t) noexcept {}
910 };
911
912 } // namespace boost::corosio::socket_option
913
914 #endif // BOOST_COROSIO_SOCKET_OPTION_HPP
915