public Endpoint Bind(UdpEndpoint endpoint) { Debug.Assert(_incoming); try { if (Network.IsMulticast(_addr)) { Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ExclusiveAddressUse, false); Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); MulticastAddress = _addr; if (OperatingSystem.IsWindows()) { // Windows does not allow binding to the multicast address itself so we bind to INADDR_ANY // instead. As a result, bidirectional connection won't work because the source address won't // be the multicast address and the client will therefore reject the datagram. if (_addr.AddressFamily == AddressFamily.InterNetwork) { _addr = new IPEndPoint(IPAddress.Any, _addr.Port); } else { _addr = new IPEndPoint(IPAddress.IPv6Any, _addr.Port); } } Socket.Bind(_addr); _addr = (IPEndPoint)Socket.LocalEndPoint !; if (endpoint.Port == 0) { MulticastAddress.Port = _addr.Port; } Network.SetMulticastGroup(Socket, MulticastAddress.Address, _multicastInterface); } else { Socket.Bind(_addr); _addr = (IPEndPoint)Socket.LocalEndPoint !; } } catch (SocketException ex) { throw new TransportException(ex); } Debug.Assert(endpoint != null); return(endpoint.Clone((ushort)_addr.Port)); }
// // Only for use by UdpConnector. // internal UdpTransceiver(Communicator communicator, string transport, EndPoint addr, IPAddress?sourceAddr, string mcastInterface, int mcastTtl) { _communicator = communicator; Transport = transport; _addr = addr; if (sourceAddr != null) { _sourceAddr = new IPEndPoint(sourceAddr, 0); } _readEventArgs = new SocketAsyncEventArgs(); _readEventArgs.RemoteEndPoint = _addr; _readEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IoCompleted); _writeEventArgs = new SocketAsyncEventArgs(); _writeEventArgs.RemoteEndPoint = _addr; _writeEventArgs.Completed += new EventHandler <SocketAsyncEventArgs>(IoCompleted); _mcastInterface = mcastInterface; _state = StateNeedConnect; _incoming = false; try { _fd = Network.CreateSocket(true, _addr.AddressFamily); SetBufSize(-1, -1); Network.SetBlock(_fd, false); if (Network.IsMulticast((IPEndPoint)_addr)) { if (_mcastInterface.Length > 0) { Network.SetMcastInterface(_fd, _mcastInterface, _addr.AddressFamily); } if (mcastTtl != -1) { Network.SetMcastTtl(_fd, mcastTtl, _addr.AddressFamily); } } } catch (System.Exception) { _fd = null; throw; } }
// Only for use by UdpConnector. internal UdpSocket( Communicator communicator, IConnector connector, EndPoint addr, IPAddress?sourceAddr, string?multicastInterface, int multicastTtl) { _communicator = communicator; _connector = connector; _addr = (IPEndPoint)addr; _multicastInterface = multicastInterface; _incoming = false; if (sourceAddr != null) { _sourceAddr = new IPEndPoint(sourceAddr, 0); } Socket = Network.CreateSocket(true, _addr.AddressFamily, _connector); try { Network.SetBufSize(Socket, _communicator, Transport.UDP); _rcvSize = (int)Socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer) !; _sndSize = (int)Socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer) !; if (Network.IsMulticast(_addr)) { if (_multicastInterface != null) { Debug.Assert(_multicastInterface.Length > 0); Network.SetMulticastInterface(Socket, _multicastInterface, _addr.AddressFamily); } if (multicastTtl != -1) { Network.SetMulticastTtl(Socket, multicastTtl, _addr.AddressFamily); } } } catch (SocketException ex) { Socket.CloseNoThrow(); throw new TransportException(ex, RetryPolicy.NoRetry, _connector); } }
public Endpoint Bind() { Debug.Assert(_fd != null); if (Network.IsMulticast((IPEndPoint)_addr)) { Network.SetReuseAddress(_fd, true); _mcastAddr = (IPEndPoint)_addr; if (AssemblyUtil.IsWindows) { // // Windows does not allow binding to the mcast address itself // so we bind to INADDR_ANY (0.0.0.0) instead. As a result, // bi-directional connection won't work because the source // address won't the multicast address and the client will // therefore reject the datagram. // if (_addr.AddressFamily == AddressFamily.InterNetwork) { _addr = new IPEndPoint(IPAddress.Any, _port); } else { _addr = new IPEndPoint(IPAddress.IPv6Any, _port); } } _addr = Network.DoBind(_fd, _addr); if (_port == 0) { _mcastAddr.Port = ((IPEndPoint)_addr).Port; } Debug.Assert(_mcastInterface != null); Network.SetMcastGroup(_fd, _mcastAddr.Address, _mcastInterface); } else { _addr = Network.DoBind(_fd, _addr); } _bound = true; Debug.Assert(_endpoint != null); _endpoint = (UdpEndpoint)_endpoint.NewPort(EffectivePort()); return(_endpoint); }