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 662 : 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 64 : bool value() const noexcept
67 : {
68 64 : 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 654 : void const* data() const noexcept
91 : {
92 654 : return &value_;
93 : }
94 :
95 : /// Return the size of the underlying storage.
96 743 : std::size_t size() const noexcept
97 : {
98 743 : 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 68 : void resize(std::size_t s) noexcept
108 : {
109 68 : if (s == sizeof(char))
110 2 : value_ = *reinterpret_cast<unsigned char*>(&value_) ? 1 : 0;
111 68 : }
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 87 : 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 62 : int value() const noexcept
142 : {
143 62 : 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 60 : void resize(std::size_t s) noexcept
169 : {
170 60 : if (s == sizeof(char))
171 2 : value_ =
172 2 : static_cast<int>(*reinterpret_cast<unsigned char*>(&value_));
173 60 : }
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 : {
265 4 : }
266 :
267 : /// Assign a new value; truncated to one byte.
268 : byte_integer_option& operator=(int v) noexcept
269 : {
270 : value_ = static_cast<unsigned char>(v);
271 : return *this;
272 : }
273 :
274 : /// Return the option value.
275 4 : int value() const noexcept
276 : {
277 4 : return value_;
278 : }
279 :
280 : /// Return a pointer to the underlying storage.
281 4 : void* data() noexcept
282 : {
283 4 : return &value_;
284 : }
285 :
286 : /// Return a pointer to the underlying storage.
287 4 : void const* data() const noexcept
288 : {
289 4 : return &value_;
290 : }
291 :
292 : /// Return the size of the underlying storage.
293 8 : std::size_t size() const noexcept
294 : {
295 8 : return sizeof(value_);
296 : }
297 :
298 : /// Storage is already one byte; no normalization needed.
299 4 : void resize(std::size_t) noexcept {}
300 : };
301 :
302 : /** Disable Nagle's algorithm (TCP_NODELAY).
303 :
304 : @par Example
305 : @par !example no_delay
306 : */
307 : class BOOST_COROSIO_DECL no_delay : public boolean_option
308 : {
309 : public:
310 : using boolean_option::boolean_option;
311 : using boolean_option::operator=;
312 :
313 : /// Return the protocol level.
314 : static int level() noexcept;
315 :
316 : /// Return the option name.
317 : static int name() noexcept;
318 : };
319 :
320 : /** Enable periodic keepalive probes (SO_KEEPALIVE).
321 :
322 : @par Example
323 : @par !example keep_alive
324 : */
325 : class BOOST_COROSIO_DECL keep_alive : public boolean_option
326 : {
327 : public:
328 : using boolean_option::boolean_option;
329 : using boolean_option::operator=;
330 :
331 : /// Return the protocol level.
332 : static int level() noexcept;
333 :
334 : /// Return the option name.
335 : static int name() noexcept;
336 : };
337 :
338 : /** Restrict an IPv6 socket to IPv6 only (IPV6_V6ONLY).
339 :
340 : When enabled, the socket only accepts IPv6 connections.
341 : When disabled, the socket accepts both IPv4 and IPv6
342 : connections (dual-stack mode).
343 :
344 : @par Example
345 : @par !example v6_only
346 : */
347 : class BOOST_COROSIO_DECL v6_only : public boolean_option
348 : {
349 : public:
350 : using boolean_option::boolean_option;
351 : using boolean_option::operator=;
352 :
353 : /// Return the protocol level.
354 : static int level() noexcept;
355 :
356 : /// Return the option name.
357 : static int name() noexcept;
358 : };
359 :
360 : /** Allow local address reuse (SO_REUSEADDR).
361 :
362 : @par Example
363 : @par !example reuse_address
364 : */
365 : class BOOST_COROSIO_DECL reuse_address : public boolean_option
366 : {
367 : public:
368 : using boolean_option::boolean_option;
369 : using boolean_option::operator=;
370 :
371 : /// Return the protocol level.
372 : static int level() noexcept;
373 :
374 : /// Return the option name.
375 : static int name() noexcept;
376 : };
377 :
378 : /** Allow sending to broadcast addresses (SO_BROADCAST).
379 :
380 : Required for UDP sockets that send to broadcast addresses
381 : such as 255.255.255.255. Without this option, `send_to`
382 : returns an error.
383 :
384 : @par Example
385 : @par !example broadcast
386 : */
387 : class BOOST_COROSIO_DECL broadcast : public boolean_option
388 : {
389 : public:
390 : using boolean_option::boolean_option;
391 : using boolean_option::operator=;
392 :
393 : /// Return the protocol level.
394 : static int level() noexcept;
395 :
396 : /// Return the option name.
397 : static int name() noexcept;
398 : };
399 :
400 : /** Allow multiple sockets to bind to the same port (SO_REUSEPORT).
401 :
402 : Not available on all platforms. On unsupported platforms,
403 : `set_option` throws `std::system_error`.
404 :
405 : @par Example
406 : @par !example reuse_port
407 : */
408 : class BOOST_COROSIO_DECL reuse_port : public boolean_option
409 : {
410 : public:
411 : using boolean_option::boolean_option;
412 : using boolean_option::operator=;
413 :
414 : /// Return the protocol level.
415 : static int level() noexcept;
416 :
417 : /// Return the option name.
418 : static int name() noexcept;
419 : };
420 :
421 : /** Set the receive buffer size (SO_RCVBUF).
422 :
423 : @par Example
424 : @par !example receive_buffer_size
425 : */
426 : class BOOST_COROSIO_DECL receive_buffer_size : public integer_option
427 : {
428 : public:
429 : using integer_option::integer_option;
430 : using integer_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 send buffer size (SO_SNDBUF).
440 :
441 : @par Example
442 : @par !example send_buffer_size
443 : */
444 : class BOOST_COROSIO_DECL send_buffer_size : public integer_option
445 : {
446 : public:
447 : using integer_option::integer_option;
448 : using integer_option::operator=;
449 :
450 : /// Return the protocol level.
451 : static int level() noexcept;
452 :
453 : /// Return the option name.
454 : static int name() noexcept;
455 : };
456 :
457 : /** The SO_LINGER socket option.
458 :
459 : Controls behavior when closing a socket with unsent data.
460 : When enabled, `close()` blocks until pending data is sent
461 : or the timeout expires.
462 :
463 : @par Example
464 : @par !example linger
465 : */
466 : class BOOST_COROSIO_DECL linger
467 : {
468 : // Opaque storage for the platform's struct linger.
469 : // POSIX: { int, int } = 8 bytes.
470 : // Windows: { u_short, u_short } = 4 bytes.
471 : static constexpr std::size_t max_storage_ = 8;
472 : alignas(4) unsigned char storage_[max_storage_]{};
473 :
474 : public:
475 : /// Construct with default values (disabled, zero timeout).
476 : linger() noexcept = default;
477 :
478 : /** Construct with explicit values.
479 :
480 : @param enabled `true` to enable linger behavior on close.
481 : @param timeout The linger timeout in seconds.
482 : */
483 : linger(bool enabled, int timeout) noexcept;
484 :
485 : /// Return whether linger is enabled.
486 : bool enabled() const noexcept;
487 :
488 : /// Set whether linger is enabled.
489 : void enabled(bool v) noexcept;
490 :
491 : /// Return the linger timeout in seconds.
492 : int timeout() const noexcept;
493 :
494 : /// Set the linger timeout in seconds.
495 : void timeout(int v) noexcept;
496 :
497 : /// Return the protocol level.
498 : static int level() noexcept;
499 :
500 : /// Return the option name.
501 : static int name() noexcept;
502 :
503 : /// Return a pointer to the underlying storage.
504 12 : void* data() noexcept
505 : {
506 12 : return storage_;
507 : }
508 :
509 : /// Return a pointer to the underlying storage.
510 203 : void const* data() const noexcept
511 : {
512 203 : return storage_;
513 : }
514 :
515 : /// Return the size of the underlying storage.
516 : std::size_t size() const noexcept;
517 :
518 : /** Normalize after `getsockopt`.
519 :
520 : No-op — `struct linger` is always returned at full size.
521 :
522 : @param s The number of bytes actually written by `getsockopt`.
523 : */
524 12 : void resize(std::size_t) noexcept {}
525 : };
526 :
527 : /** Enable loopback of outgoing multicast on IPv4 (IP_MULTICAST_LOOP).
528 :
529 : Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
530 : reject the four-byte form with `EINVAL`. Linux accepts either size.
531 :
532 : @par Example
533 : @par !example multicast_loop_v4
534 : */
535 : class BOOST_COROSIO_DECL multicast_loop_v4 : public byte_boolean_option
536 : {
537 : public:
538 : using byte_boolean_option::byte_boolean_option;
539 : using byte_boolean_option::operator=;
540 :
541 : /// Return the protocol level.
542 : static int level() noexcept;
543 :
544 : /// Return the option name.
545 : static int name() noexcept;
546 : };
547 :
548 : /** Enable loopback of outgoing multicast on IPv6 (IPV6_MULTICAST_LOOP).
549 :
550 : @par Example
551 : @par !example multicast_loop_v6
552 : */
553 : class BOOST_COROSIO_DECL multicast_loop_v6 : public boolean_option
554 : {
555 : public:
556 : using boolean_option::boolean_option;
557 : using boolean_option::operator=;
558 :
559 : /// Return the protocol level.
560 : static int level() noexcept;
561 :
562 : /// Return the option name.
563 : static int name() noexcept;
564 : };
565 :
566 : /** Set the multicast TTL for IPv4 (IP_MULTICAST_TTL).
567 :
568 : Uses single-byte storage because BSD-derived kernels (macOS, FreeBSD)
569 : reject the four-byte form with `EINVAL`. Linux accepts either size.
570 : Values are truncated to the 0–255 range.
571 :
572 : @par Example
573 : @par !example multicast_hops_v4
574 : */
575 : class BOOST_COROSIO_DECL multicast_hops_v4 : public byte_integer_option
576 : {
577 : public:
578 : using byte_integer_option::byte_integer_option;
579 : using byte_integer_option::operator=;
580 :
581 : /// Return the protocol level.
582 : static int level() noexcept;
583 :
584 : /// Return the option name.
585 : static int name() noexcept;
586 : };
587 :
588 : /** Set the multicast hop limit for IPv6 (IPV6_MULTICAST_HOPS).
589 :
590 : @par Example
591 : @par !example multicast_hops_v6
592 : */
593 : class BOOST_COROSIO_DECL multicast_hops_v6 : public integer_option
594 : {
595 : public:
596 : using integer_option::integer_option;
597 : using integer_option::operator=;
598 :
599 : /// Return the protocol level.
600 : static int level() noexcept;
601 :
602 : /// Return the option name.
603 : static int name() noexcept;
604 : };
605 :
606 : /** Set the outgoing interface for IPv6 multicast (IPV6_MULTICAST_IF).
607 :
608 : @par Example
609 : @par !example multicast_interface_v6
610 : */
611 : class BOOST_COROSIO_DECL multicast_interface_v6 : public integer_option
612 : {
613 : public:
614 : using integer_option::integer_option;
615 : using integer_option::operator=;
616 :
617 : /// Return the protocol level.
618 : static int level() noexcept;
619 :
620 : /// Return the option name.
621 : static int name() noexcept;
622 : };
623 :
624 : /** Join an IPv4 multicast group (IP_ADD_MEMBERSHIP).
625 :
626 : @par Example
627 : @par !example join_group_v4
628 : */
629 : class BOOST_COROSIO_DECL join_group_v4
630 : {
631 : static constexpr std::size_t max_storage_ = 8;
632 : alignas(4) unsigned char storage_[max_storage_]{};
633 :
634 : public:
635 : /// Construct with default values.
636 : join_group_v4() noexcept = default;
637 :
638 : /** Construct with a group and optional interface address.
639 :
640 : @param group The multicast group address to join.
641 : @param iface The local interface to use (default: any).
642 : */
643 : join_group_v4(
644 : ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
645 :
646 : /// Return the protocol level.
647 : static int level() noexcept;
648 :
649 : /// Return the option name.
650 : static int name() noexcept;
651 :
652 : /// Return a pointer to the underlying storage.
653 : void* data() noexcept
654 : {
655 : return storage_;
656 : }
657 :
658 : /// Return a pointer to the underlying storage.
659 4 : void const* data() const noexcept
660 : {
661 4 : return storage_;
662 : }
663 :
664 : /// Return the size of the underlying storage.
665 : std::size_t size() const noexcept;
666 :
667 : /// No-op resize.
668 : void resize(std::size_t) noexcept {}
669 : };
670 :
671 : /** Leave an IPv4 multicast group (IP_DROP_MEMBERSHIP).
672 :
673 : @par Example
674 : @par !example leave_group_v4
675 : */
676 : class BOOST_COROSIO_DECL leave_group_v4
677 : {
678 : static constexpr std::size_t max_storage_ = 8;
679 : alignas(4) unsigned char storage_[max_storage_]{};
680 :
681 : public:
682 : /// Construct with default values.
683 : leave_group_v4() noexcept = default;
684 :
685 : /** Construct with a group and optional interface address.
686 :
687 : @param group The multicast group address to leave.
688 : @param iface The local interface (default: any).
689 : */
690 : leave_group_v4(
691 : ipv4_address group, ipv4_address iface = ipv4_address()) noexcept;
692 :
693 : /// Return the protocol level.
694 : static int level() noexcept;
695 :
696 : /// Return the option name.
697 : static int name() noexcept;
698 :
699 : /// Return a pointer to the underlying storage.
700 : void* data() noexcept
701 : {
702 : return storage_;
703 : }
704 :
705 : /// Return a pointer to the underlying storage.
706 2 : void const* data() const noexcept
707 : {
708 2 : return storage_;
709 : }
710 :
711 : /// Return the size of the underlying storage.
712 : std::size_t size() const noexcept;
713 :
714 : /// No-op resize.
715 : void resize(std::size_t) noexcept {}
716 : };
717 :
718 : /** Join an IPv6 multicast group (IPV6_JOIN_GROUP).
719 :
720 : @par Example
721 : @par !example join_group_v6
722 : */
723 : class BOOST_COROSIO_DECL join_group_v6
724 : {
725 : static constexpr std::size_t max_storage_ = 20;
726 : alignas(4) unsigned char storage_[max_storage_]{};
727 :
728 : public:
729 : /// Construct with default values.
730 : join_group_v6() noexcept = default;
731 :
732 : /** Construct with a group and optional interface index.
733 :
734 : @param group The multicast group address to join.
735 : @param if_index The interface index (0 = kernel chooses).
736 : */
737 : join_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
738 :
739 : /// Return the protocol level.
740 : static int level() noexcept;
741 :
742 : /// Return the option name.
743 : static int name() noexcept;
744 :
745 : /// Return a pointer to the underlying storage.
746 : void* data() noexcept
747 : {
748 : return storage_;
749 : }
750 :
751 : /// Return a pointer to the underlying storage.
752 2 : void const* data() const noexcept
753 : {
754 2 : return storage_;
755 : }
756 :
757 : /// Return the size of the underlying storage.
758 : std::size_t size() const noexcept;
759 :
760 : /// No-op resize.
761 : void resize(std::size_t) noexcept {}
762 : };
763 :
764 : /** Leave an IPv6 multicast group (IPV6_LEAVE_GROUP).
765 :
766 : @par Example
767 : @par !example leave_group_v6
768 : */
769 : class BOOST_COROSIO_DECL leave_group_v6
770 : {
771 : static constexpr std::size_t max_storage_ = 20;
772 : alignas(4) unsigned char storage_[max_storage_]{};
773 :
774 : public:
775 : /// Construct with default values.
776 : leave_group_v6() noexcept = default;
777 :
778 : /** Construct with a group and optional interface index.
779 :
780 : @param group The multicast group address to leave.
781 : @param if_index The interface index (0 = kernel chooses).
782 : */
783 : leave_group_v6(ipv6_address group, unsigned int if_index = 0) noexcept;
784 :
785 : /// Return the protocol level.
786 : static int level() noexcept;
787 :
788 : /// Return the option name.
789 : static int name() noexcept;
790 :
791 : /// Return a pointer to the underlying storage.
792 2 : void* data() noexcept
793 : {
794 2 : return storage_;
795 : }
796 :
797 : /// Return a pointer to the underlying storage.
798 2 : void const* data() const noexcept
799 : {
800 2 : return storage_;
801 : }
802 :
803 : /// Return the size of the underlying storage.
804 : std::size_t size() const noexcept;
805 :
806 : /// No-op resize.
807 : void resize(std::size_t) noexcept {}
808 : };
809 :
810 : /** Set the outgoing interface for IPv4 multicast (IP_MULTICAST_IF).
811 :
812 : Unlike the integer-based `multicast_interface_v6`, this option
813 : takes an `ipv4_address` identifying the local interface.
814 :
815 : @par Example
816 : @par !example multicast_interface_v4
817 : */
818 : class BOOST_COROSIO_DECL multicast_interface_v4
819 : {
820 : static constexpr std::size_t max_storage_ = 4;
821 : alignas(4) unsigned char storage_[max_storage_]{};
822 :
823 : public:
824 : /// Construct with default values (INADDR_ANY).
825 : multicast_interface_v4() noexcept = default;
826 :
827 : /** Construct with an interface address.
828 :
829 : @param iface The local interface address.
830 : */
831 : explicit multicast_interface_v4(ipv4_address iface) noexcept;
832 :
833 : /// Return the protocol level.
834 : static int level() noexcept;
835 :
836 : /// Return the option name.
837 : static int name() noexcept;
838 :
839 : /// Return a pointer to the underlying storage.
840 : void* data() noexcept
841 : {
842 : return storage_;
843 : }
844 :
845 : /// Return a pointer to the underlying storage.
846 2 : void const* data() const noexcept
847 : {
848 2 : return storage_;
849 : }
850 :
851 : /// Return the size of the underlying storage.
852 : std::size_t size() const noexcept;
853 :
854 : /// No-op resize.
855 : void resize(std::size_t) noexcept {}
856 : };
857 :
858 : } // namespace boost::corosio::socket_option
859 :
860 : #endif // BOOST_COROSIO_SOCKET_OPTION_HPP
|