include/boost/corosio/socket_option.hpp

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