From 4ae0afb12b6d29c8bb743c4fd560a91fd626b558 Mon Sep 17 00:00:00 2001 From: Will Young Date: Sat, 23 Jul 2016 22:30:58 +0200 Subject: [PATCH] dgram: added setMulticastInterface() Add wrapper for uv's uv_udp_set_multicast_interface which provides the sender side mechanism to explicitly select an interface. The equivalent receiver side mechanism is the optional 2nd argument of addMembership(). PR-URL: https://github.com/nodejs/node/pull/7855 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Matteo Collina --- doc/api/dgram.md | 81 +++++ lib/dgram.js | 15 + src/udp_wrap.cc | 17 + src/udp_wrap.h | 2 + .../test-dgram-multicast-multi-process.js | 4 +- .../test-dgram-multicast-set-interface-lo.js | 293 ++++++++++++++++++ .../test-dgram-multicast-set-interface.js | 119 +++++++ 7 files changed, 530 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-dgram-multicast-set-interface-lo.js create mode 100644 test/parallel/test-dgram-multicast-set-interface.js diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 38675223e9991e..c837d2d7232d92 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -386,6 +386,84 @@ added: v0.6.9 Sets or clears the `SO_BROADCAST` socket option. When set to `true`, UDP packets may be sent to a local interface's broadcast address. +### socket.setMulticastInterface(multicastInterface) + + +* `multicastInterface` {String} + +*Note: All references to scope in this section are refering to +[IPv6 Zone Indices][], which are defined by [RFC 4007][]. In string form, an IP +with a scope index is written as `'IP%scope'` where scope is an interface name or +interface number.* + +Sets the default outgoing multicast interface of the socket to a chosen +interface or back to system interface selection. The `multicastInterface` must +be a valid string representation of an IP from the socket's family. + +For IPv4 sockets, this should be the IP configured for the desired physical +interface. All packets sent to multicast on the socket will be sent on the +interface determined by the most recent successful use of this call. + +For IPv6 sockets, `multicastInterface` should include a scope to indicate the +interface as in the examples that follow. In IPv6, individual `send` calls can +also use explicit scope in addresses, so only packets sent to a multicast +address without specifying an explicit scope are affected by the most recent +successful use of this call. + +#### Examples: IPv6 Outgoing Multicast Interface + +On most systems, where scope format uses the interface name: + +```js +const socket = dgram.createSocket('udp6'); + +socket.bind(1234, () => { + socket.setMulticastInterface('::%eth1'); +}); +``` + +On Windows, where scope format uses an interface number: + +```js +const socket = dgram.createSocket('udp6'); + +socket.bind(1234, () => { + socket.setMulticastInterface('::%2'); +}); +``` + +#### Example: IPv4 Outgoing Multicast Interface +All systems use an IP of the host on the desired physical interface: +```js +const socket = dgram.createSocket('udp4'); + +socket.bind(1234, () => { + socket.setMulticastInterface('10.0.0.2'); +}); +``` + +#### Call Results + +A call on a socket that is not ready to send or no longer open may throw a *Not +running* [`Error`][]. + +If `multicastInterface` can not be parsed into an IP then an *EINVAL* +[`System Error`][] is thrown. + +On IPv4, if `multicastInterface` is a valid address but does not match any +interface, or if the address does not match the family then +a [`System Error`][] such as `EADDRNOTAVAIL` or `EPROTONOSUP` is thrown. + +On IPv6, most errors with specifying or omiting scope will result in the socket +continuing to use (or returning to) the system's default interface selection. + +A socket's address family's ANY address (IPv4 `'0.0.0.0'` or IPv6 `'::'`) can be +used to return control of the sockets default outgoing interface to the system +for future multicast packets. + + ### socket.setMulticastLoopback(flag)