TLA Line data 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 HIT 658 : explicit boolean_option(bool v) noexcept : value_(v ? 1 : 0) {}
57 :
58 : /// Assign a new value.
59 4 : boolean_option& operator=(bool v) noexcept
60 : {
61 4 : value_ = v ? 1 : 0;
62 4 : return *this;
63 : }
64 :
65 : /// Return the option value.
66 62 : bool value() const noexcept
67 : {
68 62 : return value_ != 0;
69 : }
70 :
71 : /// Return the option value.
72 4 : explicit operator bool() const noexcept
73 : {
74 4 : return value_ != 0;
75 : }
76 :
77 : /// Return the negated option value.
78 4 : bool operator!() const noexcept
79 : {
80 4 : return value_ == 0;
81 : }
82 :
83 : /// Return a pointer to the underlying storage.
84 89 : void* data() noexcept
85 : {
86 89 : return &value_;
87 : }
88 :
89 : /// Return a pointer to the underlying storage.
90 652 : void const* data() const noexcept
91 : {
92 652 : return &value_;
93 : }
94 :
95 : /// Return the size of the underlying storage.
96 741 : std::size_t size() const noexcept
97 : {
98 741 : 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 66 : void resize(std::size_t s) noexcept
108 : {
109 66 : if (s == sizeof(char))
110 MIS 0 : value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
111 HIT 66 : }
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 85 : explicit integer_option(int v) noexcept : value_(v) {}
132 :
133 : /// Assign a new value.
134 2 : integer_option& operator=(int v) noexcept
135 : {
136 2 : value_ = v;
137 2 : return *this;
138 : }
139 :
140 : /// Return the option value.
141 60 : int value() const noexcept
142 : {
143 60 : return value_;
144 : }
145 :
146 : /// Return a pointer to the underlying storage.
147 58 : void* data() noexcept
148 : {
149 58 : return &value_;
150 : }
151 :
152 : /// Return a pointer to the underlying storage.
153 81 : void const* data() const noexcept
154 : {
155 81 : return &value_;
156 : }
157 :
158 : /// Return the size of the underlying storage.
159 139 : std::size_t size() const noexcept
160 : {
161 139 : 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 58 : void resize(std::size_t s) noexcept
169 : {
170 58 : if (s == sizeof(char))
171 MIS 0 : value_ =
172 0 : static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
173 HIT 58 : }
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 10 : 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 8 : bool value() const noexcept
206 : {
207 8 : 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 8 : void* data() noexcept
224 : {
225 8 : return &value_;
226 : }
227 :
228 : /// Return a pointer to the underlying storage.
229 10 : void const* data() const noexcept
230 : {
231 10 : return &value_;
232 : }
233 :
234 : /// Return the size of the underlying storage.
235 18 : std::size_t size() const noexcept
236 : {
237 18 : return sizeof(value_);
238 : }
239 :
240 : /// Storage is already one byte; no normalization needed.
241 8 : 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 4 : explicit byte_integer_option(int v) noexcept
263 4 : : value_(static_cast<unsigned char>(v))
264 4 : {}
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 4 : int value() const noexcept
275 : {
276 4 : return value_;
277 : }
278 :
279 : /// Return a pointer to the underlying storage.
280 4 : void* data() noexcept
281 : {
282 4 : return &value_;
283 : }
284 :
285 : /// Return a pointer to the underlying storage.
286 4 : void const* data() const noexcept
287 : {
288 4 : return &value_;
289 : }
290 :
291 : /// Return the size of the underlying storage.
292 8 : std::size_t size() const noexcept
293 : {
294 8 : return sizeof(value_);
295 : }
296 :
297 : /// Storage is already one byte; no normalization needed.
298 4 : 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 12 : void* data() noexcept
504 : {
505 12 : return storage_;
506 : }
507 :
508 : /// Return a pointer to the underlying storage.
509 203 : void const* data() const noexcept
510 : {
511 203 : 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 12 : 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 4 : void const* data() const noexcept
659 : {
660 4 : 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 2 : void const* data() const noexcept
706 : {
707 2 : 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 2 : void const* data() const noexcept
752 : {
753 2 : 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 2 : void* data() noexcept
792 : {
793 2 : return storage_;
794 : }
795 :
796 : /// Return a pointer to the underlying storage.
797 2 : void const* data() const noexcept
798 : {
799 2 : 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 2 : void const* data() const noexcept
846 : {
847 2 : 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
|