Coverage Report

Created: 2026-04-29 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/swift-nio/Sources/NIOCore/MulticastChannel.swift
Line
Count
Source
1
//===----------------------------------------------------------------------===//
2
//
3
// This source file is part of the SwiftNIO open source project
4
//
5
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
6
// Licensed under Apache License v2.0
7
//
8
// See LICENSE.txt for license information
9
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10
//
11
// SPDX-License-Identifier: Apache-2.0
12
//
13
//===----------------------------------------------------------------------===//
14
15
/// A `MulticastChannel` is a `Channel` that supports IP multicast operations: that is, a channel that can join multicast
16
/// groups.
17
///
18
/// - Note: As with `Channel`, all operations on a `MulticastChannel` are thread-safe.
19
public protocol MulticastChannel: Channel {
20
    /// Request that the `MulticastChannel` join the multicast group given by `group`.
21
    ///
22
    /// - Parameters:
23
    ///   - group: The IP address corresponding to the relevant multicast group.
24
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
25
    ///         `nil` if you are not interested in the result of the operation.
26
    func joinGroup(_ group: SocketAddress, promise: EventLoopPromise<Void>?)
27
28
    #if !os(Windows) && !os(WASI)
29
    /// Request that the `MulticastChannel` join the multicast group given by `group` on the interface
30
    /// given by `interface`.
31
    ///
32
    /// - Parameters:
33
    ///   - group: The IP address corresponding to the relevant multicast group.
34
    ///   - interface: The interface on which to join the given group, or `nil` to allow the kernel to choose.
35
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
36
    ///         `nil` if you are not interested in the result of the operation.
37
    @available(*, deprecated, renamed: "joinGroup(_:device:promise:)")
38
    func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise<Void>?)
39
    #endif
40
41
    /// Request that the `MulticastChannel` join the multicast group given by `group` on the device
42
    /// given by `device`.
43
    ///
44
    /// - Parameters:
45
    ///   - group: The IP address corresponding to the relevant multicast group.
46
    ///   - device: The device on which to join the given group, or `nil` to allow the kernel to choose.
47
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
48
    ///         `nil` if you are not interested in the result of the operation.
49
    func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise<Void>?)
50
51
    /// Request that the `MulticastChannel` leave the multicast group given by `group`.
52
    ///
53
    /// - Parameters:
54
    ///   - group: The IP address corresponding to the relevant multicast group.
55
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
56
    ///         `nil` if you are not interested in the result of the operation.
57
    func leaveGroup(_ group: SocketAddress, promise: EventLoopPromise<Void>?)
58
59
    #if !os(Windows) && !os(WASI)
60
    /// Request that the `MulticastChannel` leave the multicast group given by `group` on the interface
61
    /// given by `interface`.
62
    ///
63
    /// - Parameters:
64
    ///   - group: The IP address corresponding to the relevant multicast group.
65
    ///   - interface: The interface on which to leave the given group, or `nil` to allow the kernel to choose.
66
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
67
    ///         `nil` if you are not interested in the result of the operation.
68
    @available(*, deprecated, renamed: "leaveGroup(_:device:promise:)")
69
    func leaveGroup(_ group: SocketAddress, interface: NIONetworkInterface?, promise: EventLoopPromise<Void>?)
70
    #endif
71
72
    /// Request that the `MulticastChannel` leave the multicast group given by `group` on the device
73
    /// given by `device`.
74
    ///
75
    /// - Parameters:
76
    ///   - group: The IP address corresponding to the relevant multicast group.
77
    ///   - device: The device on which to leave the given group, or `nil` to allow the kernel to choose.
78
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
79
    ///         `nil` if you are not interested in the result of the operation.
80
    func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise<Void>?)
81
}
82
83
// MARK:- Default implementations for MulticastChannel
84
extension MulticastChannel {
85
0
    public func joinGroup(_ group: SocketAddress, promise: EventLoopPromise<Void>?) {
86
0
        self.joinGroup(group, device: nil, promise: promise)
87
0
    }
88
89
0
    public func joinGroup(_ group: SocketAddress) -> EventLoopFuture<Void> {
90
0
        let promise = self.eventLoop.makePromise(of: Void.self)
91
0
        self.joinGroup(group, promise: promise)
92
0
        return promise.futureResult
93
0
    }
94
95
    #if !os(Windows) && !os(WASI)
96
    @available(*, deprecated, renamed: "joinGroup(_:device:)")
97
0
    public func joinGroup(_ group: SocketAddress, interface: NIONetworkInterface?) -> EventLoopFuture<Void> {
98
0
        let promise = self.eventLoop.makePromise(of: Void.self)
99
0
        self.joinGroup(group, interface: interface, promise: promise)
100
0
        return promise.futureResult
101
0
    }
102
    #endif
103
104
0
    public func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?) -> EventLoopFuture<Void> {
105
0
        let promise = self.eventLoop.makePromise(of: Void.self)
106
0
        self.joinGroup(group, device: device, promise: promise)
107
0
        return promise.futureResult
108
0
    }
109
110
0
    public func leaveGroup(_ group: SocketAddress, promise: EventLoopPromise<Void>?) {
111
0
        self.leaveGroup(group, device: nil, promise: promise)
112
0
    }
113
114
0
    public func leaveGroup(_ group: SocketAddress) -> EventLoopFuture<Void> {
115
0
        let promise = self.eventLoop.makePromise(of: Void.self)
116
0
        self.leaveGroup(group, promise: promise)
117
0
        return promise.futureResult
118
0
    }
119
120
    #if !os(Windows) && !os(WASI)
121
    @available(*, deprecated, renamed: "leaveGroup(_:device:)")
122
0
    public func leaveGroup(_ group: SocketAddress, interface: NIONetworkInterface?) -> EventLoopFuture<Void> {
123
0
        let promise = self.eventLoop.makePromise(of: Void.self)
124
0
        self.leaveGroup(group, interface: interface, promise: promise)
125
0
        return promise.futureResult
126
0
    }
127
    #endif
128
129
0
    public func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?) -> EventLoopFuture<Void> {
130
0
        let promise = self.eventLoop.makePromise(of: Void.self)
131
0
        self.leaveGroup(group, device: device, promise: promise)
132
0
        return promise.futureResult
133
0
    }
134
}
135
136
// MARK:- API Compatibility shims for MulticastChannel
137
extension MulticastChannel {
138
    /// Request that the `MulticastChannel` join the multicast group given by `group` on the device
139
    /// given by `device`.
140
    ///
141
    /// - Parameters:
142
    ///   - group: The IP address corresponding to the relevant multicast group.
143
    ///   - device: The device on which to join the given group, or `nil` to allow the kernel to choose.
144
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
145
    ///         `nil` if you are not interested in the result of the operation.
146
0
    public func joinGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise<Void>?) {
147
0
        // We just fail this in the default implementation. Users should override it.
148
0
        promise?.fail(NIOMulticastNotImplementedError())
149
0
    }
150
151
    /// Request that the `MulticastChannel` leave the multicast group given by `group` on the device
152
    /// given by `device`.
153
    ///
154
    /// - Parameters:
155
    ///   - group: The IP address corresponding to the relevant multicast group.
156
    ///   - device: The device on which to leave the given group, or `nil` to allow the kernel to choose.
157
    ///   - promise: The `EventLoopPromise` that will be notified once the operation is complete, or
158
    ///         `nil` if you are not interested in the result of the operation.
159
0
    public func leaveGroup(_ group: SocketAddress, device: NIONetworkDevice?, promise: EventLoopPromise<Void>?) {
160
0
        // We just fail this in the default implementation. Users should override it.
161
0
        promise?.fail(NIOMulticastNotImplementedError())
162
0
    }
163
}
164
165
/// Multicast is not supported on this interface.
166
public struct NIOMulticastNotSupportedError: Error {
167
    public var device: NIONetworkDevice
168
169
0
    public init(device: NIONetworkDevice) {
170
0
        self.device = device
171
0
    }
172
}
173
174
/// Multicast has not been properly implemented on this channel.
175
public struct NIOMulticastNotImplementedError: Error {
176
0
    public init() {}
177
}