Пример #1
0
 internal static unsafe Error GetIPv6MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv6MulticastOption* option)
 {
     bool release = false;
     try
     {
         socket.DangerousAddRef(ref release);
         return DangerousGetIPv6MulticastOption((int)socket.DangerousGetHandle(), multicastOption, option);
     }
     finally
     {
         if (release)
         {
             socket.DangerousRelease();
         }
     }
 }
 private static extern unsafe Error DangerousSetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption *option);
Пример #3
0
        public LocalMulticast(int port, Action <TMessage> handler = null, string name = null)
        {
            _handler = handler;
            _name    = name ?? String.Empty;

            var msgSize = TypeHelper <TMessage> .FixedSize;

            if (msgSize <= 0)
            {
                throw new ArgumentException($"Type {typeof(TMessage).Name} must be a blittable struct");
            }

            _bufferLength = msgSize;

            _sendArgsPool = new ObjectPool <SocketAsyncEventArgs>(SendArgsFactory, Environment.ProcessorCount * 4);

            var multicastAddress = IPAddress.Parse("239.199.99.9");

            _mcEndPoint = new CachedEndPoint(new IPEndPoint(multicastAddress, port));
            _inEndPoint = new CachedEndPoint(new IPEndPoint(IPAddress.Loopback, port));

            _socket = new Socket(_inEndPoint.AddressFamily,
                                 SocketType.Dgram, ProtocolType.Udp);

            _socket.SetSocketOption(SocketOptionLevel.Socket,
                                    SocketOptionName.ReuseAddress,
                                    true);

            _socket.SetSocketOption(SocketOptionLevel.Udp,
                                    SocketOptionName.NoChecksum,
                                    1);

            _socket.SetSocketOption(SocketOptionLevel.IP,
                                    SocketOptionName.MulticastTimeToLive,
                                    2);

            _socket.ExclusiveAddressUse = false;
            _socket.Blocking            = true;
            _socket.EnableBroadcast     = true;
            // Maybe a fluke, bit perf drops and definitely not improves with this: _socket.UseOnlyOverlappedIO = true;

            _socket.Bind(_inEndPoint);

            // If you are using a connectionless protocol such as UDP,
            // you do not have to call Connect before sending and
            // receiving data. You can use SendTo and ReceiveFrom to
            // synchronously communicate with a remote host.
            // If you do call Connect, any datagrams that arrive from
            // an address other than the specified default will be discarded.
            // _socket.Connect(_mcEndPoint);

            _socket.SetSocketOption(SocketOptionLevel.IP,
                                    SocketOptionName.MulticastLoopback,
                                    true);

            // join on loopback interface
            var mcastOption = new MulticastOption(multicastAddress, NetworkInterface.LoopbackInterfaceIndex);

            _socket.SetSocketOption(SocketOptionLevel.IP,
                                    SocketOptionName.AddMembership,
                                    mcastOption);

            _socket.SetSocketOption(SocketOptionLevel.IP,
                                    SocketOptionName.MulticastInterface,
#pragma warning disable 618
                                    (int)IPAddress.Loopback.Address);
#pragma warning restore 618
            // see https://github.com/dotnet/corefx/issues/25699 if there are issues on non-Windows
            // IPAddress.HostToNetworkOrder(NetworkInterface.LoopbackInterfaceIndex));

            // Another option to limit source to loopback
            //byte[] membershipAddresses = new byte[12]; // 3 IPs * 4 bytes (IPv4)
            //Buffer.BlockCopy(multicastAddress.GetAddressBytes(), 0, membershipAddresses, 0, 4);
            //Buffer.BlockCopy(IPAddress.Loopback.GetAddressBytes(), 0, membershipAddresses, 4, 4);
            //Buffer.BlockCopy(IPAddress.Loopback.GetAddressBytes(), 0, membershipAddresses, 8, 4);
            //_socket.SetSocketOption(SocketOptionLevel.IP,
            //    SocketOptionName.AddSourceMembership,
            //    membershipAddresses);

            StartReceive();

#if NETCOREAPP3_0
            try
            {
                _handle = _socket.SafeHandle;
                var address = _mcEndPoint.Serialize();
                _mcAddressSize   = address.Size;
                _mcAddressBuffer = new byte[_mcAddressSize];
                for (int i = 0; i < _mcAddressSize; i++)
                {
                    _mcAddressBuffer[i] = address[i];
                }

                var assembly      = typeof(Socket).Assembly;
                var socketPalType = assembly.GetTypes().FirstOrDefault(x => x.Name == "SocketPal");
                var method        = socketPalType?.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public)
                                    .FirstOrDefault(m => m.Name == "SendTo");

                _sendToDelegate = Delegate.CreateDelegate(typeof(SendToDelegate), method) as SendToDelegate;
            }
            catch
            {
                Trace.TraceInformation("Cannot get SocketPal.SendTo method");
            }
#endif
        }
Пример #4
0
        public async Task NetworkRequestAsync(byte[] requestBytes,
                                              TimeSpan scanTime,
                                              int retries,
                                              int retryDelayMilliseconds,
                                              Action <string, byte[]> onResponse,
                                              CancellationToken cancellationToken)
        {
            using (var client = new UdpClient())
            {
                for (var i = 0; i < retries; i++)
                {
#if ANDROID
                    var mlock = wifi.CreateMulticastLock("Zeroconf lock");
#endif
                    try
                    {
#if ANDROID
                        mlock.Acquire();
#endif

                        var localEp = new IPEndPoint(IPAddress.Any, 5353);

                        // There could be multiple adapters, get the default one
                        uint index = 0;
#if XAMARIN
                        const int ifaceIndex = 0;
#else
                        GetBestInterface(0, out index);
                        var ifaceIndex = (int)index;
#endif

                        client.Client.SetSocketOption(SocketOptionLevel.IP,
                                                      SocketOptionName.MulticastInterface,
                                                      (int)IPAddress.HostToNetworkOrder(ifaceIndex));



                        client.ExclusiveAddressUse = false;
                        client.Client.SetSocketOption(SocketOptionLevel.Socket,
                                                      SocketOptionName.ReuseAddress,
                                                      true);
                        client.Client.SetSocketOption(SocketOptionLevel.Socket,
                                                      SocketOptionName.ReceiveTimeout,
                                                      scanTime.Milliseconds);
                        client.ExclusiveAddressUse = false;

                        client.Client.Bind(localEp);

                        var multicastAddress = IPAddress.Parse("224.0.0.251");

                        var multOpt = new MulticastOption(multicastAddress, ifaceIndex);
                        client.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);


                        Debug.WriteLine("Bound to multicast address");

                        // Start a receive loop
                        var shouldCancel = false;
                        var recTask      = Task.Run(async
                                                        () =>
                        {
                            try
                            {
                                while (!shouldCancel)
                                {
                                    var res = await client.ReceiveAsync()
                                              .ConfigureAwait(false);
                                    onResponse(res.RemoteEndPoint.Address.ToString(), res.Buffer);
                                }
                            }
                            catch (ObjectDisposedException)
                            {
                            }
                        }, cancellationToken);

                        var broadcastEp = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);


                        await client.SendAsync(requestBytes, requestBytes.Length, broadcastEp)
                        .ConfigureAwait(false);

                        Debug.WriteLine("Sent mDNS query");


                        // wait for responses
                        await Task.Delay(scanTime, cancellationToken)
                        .ConfigureAwait(false);

                        shouldCancel = true;
                        client.Close();
                        Debug.WriteLine("Done Scanning");


                        await recTask.ConfigureAwait(false);

                        return;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("Execption: ", e);
                        if (i + 1 >= retries) // last one, pass underlying out
                        {
                            throw;
                        }
                    }
                    finally
                    {
#if ANDROID
                        mlock.Release();
#endif
                    }

                    await Task.Delay(retryDelayMilliseconds, cancellationToken).ConfigureAwait(false);
                }
            }
        }
Пример #5
0
        private void StartMulticastSocket(SocketSet info)
        {
            if (info._localEP.Address.IsIPv6Multicast)
            {
                try {
                    info._socket = SetupUDPSocket(AddressFamily.InterNetworkV6, ReceivePacketSize + 1);
                    info._socket.Socket.Bind(new IPEndPoint(IPAddress.IPv6Any, _port));

                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in nics)
                    {
                        if (!adapter.SupportsMulticast)
                        {
                            continue;
                        }
                        if (adapter.OperationalStatus != OperationalStatus.Up)
                        {
                            continue;
                        }
                        if (adapter.Supports(NetworkInterfaceComponent.IPv6))
                        {
                            IPInterfaceProperties properties = adapter.GetIPProperties();

                            foreach (UnicastIPAddressInformation ip in adapter.GetIPProperties().UnicastAddresses)
                            {
                                if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                                {
                                    IPv6InterfaceProperties v6ip = adapter.GetIPProperties().GetIPv6Properties();
                                    IPv6MulticastOption     mc   = new IPv6MulticastOption(info._localEP.Address, v6ip.Index);
                                    try {
                                        info._socket.Socket.SetSocketOption(SocketOptionLevel.IPv6,
                                                                            SocketOptionName.AddMembership,
                                                                            mc);
                                    }
                                    catch (SocketException e) {
#if LOG_UDP_CHANNEL
                                        _Log.Info(
                                            m => m(
                                                $"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
#endif
                                    }

                                    break;
                                }
                            }
                        }
                    }
                }
                catch (SocketException e) {
#if LOG_UDP_CHANNEL
                    _Log.Info(
                        m => m($"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
                    throw;
#endif
                }
            }
            else
            {
                try {
                    info._socket = SetupUDPSocket(AddressFamily.InterNetwork, ReceivePacketSize + 1);
                    info._socket.Socket.Bind(new IPEndPoint(IPAddress.Any, _port));

                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();


                    foreach (NetworkInterface adapter in nics)
                    {
                        if (!adapter.SupportsMulticast)
                        {
                            continue;
                        }
                        if (adapter.OperationalStatus != OperationalStatus.Up)
                        {
                            continue;
                        }
                        if (adapter.Supports(NetworkInterfaceComponent.IPv4))
                        {
                            IPInterfaceProperties properties = adapter.GetIPProperties();

                            foreach (UnicastIPAddressInformation ip in adapter.GetIPProperties().UnicastAddresses)
                            {
                                if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                                {
                                    MulticastOption mc = new MulticastOption(info._localEP.Address, ip.Address);
                                    info._socket.Socket.SetSocketOption(SocketOptionLevel.IP,
                                                                        SocketOptionName.AddMembership,
                                                                        mc);
                                }
                            }
                        }
                    }
                }
                catch (SocketException e) {
#if LOG_UDP_CHANNEL
                    _Log.Info(m => m($"Start Multicast:  Address {info._localEP.Address} had an exception ${e.ToString()}"));
#endif
                    throw;
                }
            }


            if (ReceiveBufferSize > 0)
            {
                info._socket.Socket.ReceiveBufferSize = ReceiveBufferSize;
                if (info._socketBackup != null)
                {
                    info._socketBackup.Socket.ReceiveBufferSize = ReceiveBufferSize;
                }
            }

            if (SendBufferSize > 0)
            {
                info._socket.Socket.SendBufferSize = SendBufferSize;
                if (info._socketBackup != null)
                {
                    info._socketBackup.Socket.SendBufferSize = SendBufferSize;
                }
            }

            BeginReceive(info);
        }
Пример #6
0
        /// <summary>
        /// Gets socket option value.
        /// </summary>
        /// <param name="option">Option to get.</param>
        /// <returns></returns>
        public dynamic GetOption( MulticastOption option )
        {
            switch( option )
            {
                case MulticastOption.DataRate:
                case MulticastOption.RecoveryInterval:
                case MulticastOption.RecoveryIntervalMS:
                case MulticastOption.Loopback:
                    return GetOptionInt64( (int)option );

                default:
                    throw new NotImplementedException( "Unknown option: " + option );
            }
        }
Пример #7
0
    public static void Main(String[] args)
    {
        // Initialize the multicast address group and multicast port.
        // Both address and port are selected from the allowed sets as
        // defined in the related RFC documents. These are the same
        // as the values used by the sender.
        mcastAddress = IPAddress.Parse("230.0.0.1");
        mcastPort = 11000;

        try
        {
            mcastSocket = new Socket(AddressFamily.InterNetwork,
                                     SocketType.Dgram,
                                     ProtocolType.Udp);

            IPAddress localIP = IPAddress.Any;
            EndPoint localEP = (EndPoint)new IPEndPoint(localIP, mcastPort);

            mcastSocket.SetSocketOption(SocketOptionLevel.Socket,
                                        SocketOptionName.ReuseAddress,
                                        1);

            mcastSocket.Bind(localEP);

            // Define a MulticastOption object specifying the multicast group
            // address and the local IPAddress.
            // The multicast group address is the same as the address used by the server.
            mcastOption = new MulticastOption(mcastAddress, localIP);

            // Become a member of the multicast IP address
            mcastSocket.SetSocketOption(SocketOptionLevel.IP,
                                        SocketOptionName.AddMembership,
                                        mcastOption);

            bool done = false;
            byte[] bytes = new Byte[100];
            IPEndPoint groupEP = new IPEndPoint(mcastAddress, mcastPort);
            EndPoint remoteEP = (EndPoint)new IPEndPoint(IPAddress.Any, 0);

            while (!done)
            {
                Console.WriteLine("Waiting for multicast packets.......");
                Console.WriteLine("Enter ^C to terminate.");

                mcastSocket.ReceiveFrom(bytes, ref remoteEP);

                Console.WriteLine("Received broadcast from {0} :\n {1}\n",
                remoteEP.ToString(),
                Encoding.ASCII.GetString(bytes, 0, bytes.Length));

                Array.Clear(bytes, 0, 99);
            }

            mcastSocket.Close();
        }

        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
Пример #8
0
        /// <include file='doc\UDPClient.uex' path='docs/doc[@for="UdpClient.DropMulticastGroup"]/*' />
        /// <devdoc>
        ///    <para>
        ///       Leaves a multicast address group.
        ///    </para>
        /// </devdoc>
        public void DropMulticastGroup(IPAddress multicastAddr) {
            //
            // parameter validation
            //
            if (m_CleanedUp){
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (multicastAddr==null){
                throw new ArgumentNullException("multicastAddr");
            }

            MulticastOption mcOpt = new MulticastOption(multicastAddr);

            Client.SetSocketOption(
                SocketOptionLevel.IP,
                SocketOptionName.DropMembership,
                mcOpt );
        }
Пример #9
0
        void FindNetworkInterfaces()
        {
            var nics = GetNetworkInterfaces()
                       .Where(nic => !knownNics.Any(k => k.Id == nic.Id))
                       .ToArray();

            foreach (var nic in nics)
            {
                lock (socketLock)
                {
                    if (socket == null)
                    {
                        return;
                    }

                    IPInterfaceProperties properties = nic.GetIPProperties();
                    if (ip6)
                    {
                        var ipProperties   = properties.GetIPv6Properties();
                        var interfaceIndex = ipProperties.Index;
                        var mopt           = new IPv6MulticastOption(MulticastAddressIp6, interfaceIndex);
                        socket.SetSocketOption(
                            SocketOptionLevel.IPv6,
                            SocketOptionName.AddMembership,
                            mopt);
                        if (ipProperties.Mtu > packetOverhead)
                        {
                            // Only change maxPacketSize if Mtu is available (and it that is not the case on MacOS)
                            maxPacketSize = Math.Min(maxPacketSize, ipProperties.Mtu - packetOverhead);
                        }
                    }
                    else
                    {
                        var ipProperties   = properties.GetIPv4Properties();
                        var interfaceIndex = ipProperties.Index;
                        var mopt           = new MulticastOption(MulticastAddressIp4, interfaceIndex);
                        socket.SetSocketOption(
                            SocketOptionLevel.IP,
                            SocketOptionName.AddMembership,
                            mopt);
                        if (ipProperties.Mtu > packetOverhead)
                        {
                            // Only change maxPacketSize if Mtu is available (and it that is not the case on MacOS)
                            maxPacketSize = Math.Min(maxPacketSize, ipProperties.Mtu - packetOverhead);
                        }
                    }
                    knownNics.Add(nic);
                }
            }

            // Tell others.
            if (nics.Length > 0)
            {
                lock (socketLock)
                {
                    if (socket == null)
                    {
                        return;
                    }
                    NetworkInterfaceDiscovered?.Invoke(this, new NetworkInterfaceEventArgs
                    {
                        NetworkInterfaces = nics
                    });
                }
            }
        }
Пример #10
0
        public void JoinASM(IPAddress groupIp, int port,
                            EMulticastInterface iface, IPAddress specificIface = null)
        {
            ValidateASM(groupIp, port);

            if (_udpClient != null)
            {
                return; // already started.
            }
            _udpClient = new UdpClient(groupIp.AddressFamily);
            Socket socket = _udpClient.Client;

            socket.SetSocketOption(
                SocketOptionLevel.Socket,
                SocketOptionName.ReuseAddress,
                true
                );

            var bindInterface = specificIface;

            if (iface != EMulticastInterface.Specific)
            {
                bindInterface = (socket.AddressFamily == AddressFamily.InterNetworkV6 ?
                                 IPAddress.IPv6Any : IPAddress.Any);
            }
            socket.Bind(new IPEndPoint(bindInterface, port));

            var joinInterfaces = new List <int>();

            if (iface == EMulticastInterface.All)
            {
                foreach (var ni in NetworkUtils.GetActiveInterfaces())
                {
                    joinInterfaces.Add(socket.AddressFamily == AddressFamily.InterNetworkV6
                        ? ni.IPv6.Index : ni.IPv4.Index);
                }
            }
            else if (iface == EMulticastInterface.Specific)
            {
                int best = NetworkUtils.GetBestMulticastInterfaceIndex(specificIface);
                if (best == -1)
                {
                    best = 0;
                }
                joinInterfaces.Add(best);
            }
            else if (iface == EMulticastInterface.Default)
            {
                joinInterfaces.Add(0); // 0 = default.
            }

            foreach (int ifaceIndex in joinInterfaces)
            {
                if (socket.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption opt = new MulticastOption(
                        groupIp, ifaceIndex);

                    socket.SetSocketOption(SocketOptionLevel.IP,
                                           SocketOptionName.AddMembership, opt);
                }
                else if (socket.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    IPv6MulticastOption optv6 = new IPv6MulticastOption(
                        groupIp, ifaceIndex);

                    socket.SetSocketOption(SocketOptionLevel.IPv6,
                                           SocketOptionName.AddMembership, optv6);
                }
            }

            StatusChanged?.Invoke(this,
                                  new UdpMulticastClientStatusEventArgs(true)
            {
                MulticastGroup     = new IPEndPoint(groupIp, port),
                MulticastInterface = iface,
                SpecificInterface  = specificIface
            }
                                  );

            StartReceive();
        }
Пример #11
0
        protected virtual void CreateSocket(string mcastserverPRI, int mcastportPRI, string mcastserverSEC, int mcastportSEC)
        {
            try
            {
                bKeepRunning = true;

                logger.Info("Criando socket para host:porta [" + mcastserverPRI + ":" + mcastportPRI + "]");

                //Using UDP sockets
                clientSocketPRI = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                clientSocketPRI.ReceiveBufferSize   = 1024 * 1024 * 16;
                clientSocketPRI.UseOnlyOverlappedIO = true;

                //IP address of the server machine
                ipAddressPRI = IPAddress.Parse(mcastserverPRI);
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, mcastportPRI);
                clientSocketPRI.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                clientSocketPRI.ExclusiveAddressUse = false;
                clientSocketPRI.Bind(localEndPoint);

                if (!String.IsNullOrEmpty(localInterfaceAddress) && !localInterfaceAddress.ToLowerInvariant().Equals("any"))
                {
                    logger.Info("Binding PRI local interface: [" + localInterfaceAddress + "]");
                    mcoPRI = new MulticastOption(ipAddressPRI, IPAddress.Parse(localInterfaceAddress));
                }
                else
                {
                    logger.Info("Binding PRI all interfaces");
                    mcoPRI = new MulticastOption(ipAddressPRI, IPAddress.Any);
                }
                clientSocketPRI.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcoPRI);
                clientSocketPRI.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 200);
                IPEndPoint serverEndPoint = new IPEndPoint(ipAddressPRI, mcastportPRI);

                epServerPRI = (EndPoint)serverEndPoint;

                logger.Debug("Joining primary group...");

                byteDataPRI = new byte[BUFFER_SIZE];

                logger.Info("Start primary receiving");

                clientSocketPRI.BeginReceiveFrom(byteDataPRI, 0, byteDataPRI.Length, SocketFlags.None, ref epServerPRI,
                                                 new AsyncCallback(this.OnReceivePRI), null);

                if (!String.IsNullOrEmpty(mcastserverSEC))
                {
                    logger.Info("Criando socket para host:porta [" + mcastserverSEC + ":" + mcastportSEC + "]");

                    //Using UDP sockets
                    clientSocketSEC = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    clientSocketSEC.ReceiveBufferSize   = 1024 * 1024 * 16;
                    clientSocketSEC.UseOnlyOverlappedIO = true;

                    //IP address of the server machine
                    ipAddressSEC  = IPAddress.Parse(mcastserverSEC);
                    localEndPoint = new IPEndPoint(IPAddress.Any, mcastportSEC);
                    clientSocketSEC.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    clientSocketSEC.ExclusiveAddressUse = false;
                    clientSocketSEC.Bind(localEndPoint);

                    if (!String.IsNullOrEmpty(localInterfaceAddress) && !localInterfaceAddress.ToLowerInvariant().Equals("any"))
                    {
                        logger.Info("Binding SEC local interface: [" + localInterfaceAddress + "]");
                        mcoSEC = new MulticastOption(ipAddressSEC, IPAddress.Parse(localInterfaceAddress));
                    }
                    else
                    {
                        logger.Info("Binding SEC all interfaces");
                        mcoSEC = new MulticastOption(ipAddressSEC, IPAddress.Any);
                    }
                    clientSocketSEC.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mcoSEC);
                    clientSocketSEC.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 200);
                    serverEndPoint = new IPEndPoint(ipAddressSEC, mcastportSEC);

                    epServerSEC = (EndPoint)serverEndPoint;

                    logger.Debug("Joining secondary group...");

                    byteDataSEC = new byte[BUFFER_SIZE];

                    logger.Debug("Start secondary receiving");

                    clientSocketSEC.BeginReceiveFrom(byteDataSEC, 0, byteDataSEC.Length, SocketFlags.None, ref epServerSEC,
                                                     new AsyncCallback(this.OnReceiveSEC), null);
                }
            }
            catch (Exception ex)
            {
                logger.Error("CreateSocket(): " + ex.Message, ex);
                bKeepRunning = false;
            }
        }
Пример #12
0
        public void Start()
        {
            if (socket_ != null)
            {
                throw new InvalidOperationException("Network is already running");
            }

            socket_ = new Socket(broadcastEndpoint_.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

            // Bind to the broadcast port.
            socket_.Bind(new IPEndPoint(localAddress_, broadcastEndpoint_.Port));

            // Optionally join a multicast group
            if (IsMulticast(broadcastEndpoint_.Address))
            {
                if (broadcastEndpoint_.AddressFamily == AddressFamily.InterNetwork)
                {
                    MulticastOption mcastOption;
                    mcastOption = new MulticastOption(broadcastEndpoint_.Address, localAddress_);

                    socket_.SetSocketOption(SocketOptionLevel.IP,
                                            SocketOptionName.AddMembership,
                                            mcastOption);
                }
                else if (broadcastEndpoint_.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    IPv6MulticastOption mcastOption;
                    if (localAddress_ != IPAddress.IPv6Any)
                    {
                        var ifaceIdx = GetIfaceIdxFromAddress(localAddress_);
                        mcastOption = new IPv6MulticastOption(broadcastEndpoint_.Address, ifaceIdx);
                    }
                    else
                    {
                        mcastOption = new IPv6MulticastOption(broadcastEndpoint_.Address);
                    }
                    socket_.SetSocketOption(SocketOptionLevel.IP,
                                            SocketOptionName.AddMembership,
                                            mcastOption);
                }
                else
                {
                    // Should never happen
                    throw new NotSupportedException($"Invalid address family: {broadcastEndpoint_.AddressFamily}");
                }
            }
            else
            {
                // Assume this is a broadcast address.
                socket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            }

            // Start the cleanup thread.
            deleteExpiredCts_ = new CancellationTokenSource();
            var token = deleteExpiredCts_.Token;

            deleteExpiredTask_ = Task.Run(() => CleanupExpired(token), token);

            // Start the receiving thread.
            recvTask_ = Task.Run(ReceiveLoop);

            Started?.Invoke(this);
        }
Пример #13
0
 internal static extern unsafe Error GetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption *option);
Пример #14
0
        protected override void OnOpen()
        {
            System.Diagnostics.Debug.Assert(_socket == null);
            System.Diagnostics.Debug.Assert(_remoteEp != null);
            System.Diagnostics.Debug.Assert(_localIp != null);
            System.Diagnostics.Debug.Assert(_iface != null);

            try
            {
                IPEndPoint ep = _remoteEp as IPEndPoint;

                ep.Port = Port;

                _socket = OpenSocket(ep);

                _multicast = ep.Address.IsMulticast();

                if (_multicast)
                {
                    if (Platform.GetOS() == Platform.OS.Windows)
                    {
                        // Multicast needs to bind to INADDR_ANY on windows
                        if (ep.AddressFamily == AddressFamily.InterNetwork)
                        {
                            _socket.Bind(new IPEndPoint(IPAddress.Any, SrcPort));
                        }
                        else
                        {
                            _socket.Bind(new IPEndPoint(IPAddress.IPv6Any, SrcPort));
                        }
                    }
                    else if (ep.Address.AddressFamily == AddressFamily.InterNetwork)
                    {
                        // Multicast needs to bind to the group on *nix
                        _socket.Bind(new IPEndPoint(ep.Address, SrcPort));
                    }
                    else
                    {
                        _socket.Bind(new IPEndPoint(IPAddress.IPv6Any, SrcPort));
                    }

                    SocketOptionLevel level = SocketOptionLevel.IPv6;
                    object            opt   = null;

                    if (_localIp.AddressFamily == AddressFamily.InterNetwork)
                    {
                        level = SocketOptionLevel.IP;
                        opt   = new MulticastOption(ep.Address, _localIp);
                    }
                    else if (Platform.GetOS() == Platform.OS.OSX)
                    {
                        if (_iface == null)
                        {
                            throw new PeachException("Error, could not resolve local interface name for local IP '{0}'.".Fmt(_localIp));
                        }

                        uint ifindex = if_nametoindex(_iface);

                        if (ifindex == 0)
                        {
                            throw new PeachException("Error, could not resolve interface index for interface name '{0}'.".Fmt(_iface));
                        }

                        JoinGroupV6(ep.Address, ifindex);
                    }
                    else if (_localIp != IPAddress.IPv6Any)
                    {
                        level = SocketOptionLevel.IPv6;
                        opt   = new IPv6MulticastOption(ep.Address, _localIp.ScopeId);
                    }
                    else
                    {
                        level = SocketOptionLevel.IPv6;
                        opt   = new IPv6MulticastOption(ep.Address);
                    }

                    if (opt != null)
                    {
                        _socket.SetSocketOption(level, SocketOptionName.AddMembership, opt);
                    }

                    if (_localIp != IPAddress.Any && _localIp != IPAddress.IPv6Any)
                    {
                        Logger.Trace("Setting multicast interface for {0} socket to {1}.", _type, _localIp);

                        if (level == SocketOptionLevel.IP)
                        {
                            _socket.SetSocketOption(level, SocketOptionName.MulticastInterface, _localIp.GetAddressBytes());
                        }
                        else if (Platform.GetOS() != Platform.OS.OSX)
                        {
                            _socket.SetSocketOption(level, SocketOptionName.MulticastInterface, (int)_localIp.ScopeId);
                        }
                    }
                    else if (Platform.GetOS() == Platform.OS.OSX)
                    {
                        throw new PeachException(string.Format("Error, the value for parameter 'Interface' can not be '{0}' when the 'Host' parameter is multicast.", Interface == null ? "<null>" : Interface.ToString()));
                    }
                }
                else
                {
                    _socket.Bind(new IPEndPoint(_localIp, SrcPort));
                }
            }
            catch (Exception ex)
            {
                if (_socket != null)
                {
                    _socket.Close();
                    _socket = null;
                }

                SocketException se = ex as SocketException;
                if (se != null && se.SocketErrorCode == SocketError.AccessDenied)
                {
                    throw new PeachException(string.Format("Access denied when trying open a {0} socket.  Ensure the user has the appropriate permissions.", _type), ex);
                }

                Logger.Error("Unable to open {0} socket to {1}:{2}. {3}.", _type, Host, Port, ex.Message);

                throw new SoftException(ex);
            }

            _socket.ReceiveBufferSize = MaxSendSize;
            _socket.SendBufferSize    = MaxSendSize;

            if (_recvBuffer == null || _recvBuffer.Capacity < _socket.ReceiveBufferSize)
            {
                _recvBuffer = new MemoryStream(MaxSendSize);
            }

            _localEp = _socket.LocalEndPoint;

            Logger.Trace("Opened {0} socket, Local: {1}, Remote: {2}", _type, _localEp, _remoteEp);
        }
Пример #15
0
        /// <summary>
        /// Starts listening to the specified end point and accepting incoming connections.
        /// </summary>
        /// <param name="endPoint">The end point.</param>
        public override void StartListening(object endPoint)
        {
            BinaryLogWriter binaryLogWriter = this.ITransportContext.BinaryLogWriter;

            this._closing = false;

            // LOG:
            if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
            {
                binaryLogWriter.WriteConnectionParameterEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                                              LogMessageType.ConnectionParameters, null, null, this.ITransportContext.IParameterProvider,
                                                              GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name, this.DbgConnectionId,
                                                              "UDP socket is being associated with the end point: {0}.", endPoint.ToString());
            }

            // get the ip end point
            IPEndPoint ipEndPoint = null;
            int        port;
            string     url;

            try
            {
                url        = (string)endPoint;
                url        = GenuineUtility.SplitToHostAndPort(url, out port);
                ipEndPoint = new IPEndPoint(GenuineUtility.ResolveIPAddress(url), port);
            }
            catch (Exception ex)
            {
                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                               LogMessageType.ListeningStarted, ex, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null, this.DbgConnectionId, 0, 0, 0, null, null, null, null,
                                               "The listening socket cannot be associated with the {0} local end point.", endPoint.ToString());
                }

                throw GenuineExceptions.Get_Server_IncorrectAddressToListen(endPoint as string);
            }

            lock (this)
            {
                if (this._socket != null)
                {
                    throw GenuineExceptions.Get_Server_EndPointIsAlreadyBeingListenedTo(this._socket.LocalEndPoint.ToString());
                }

                // initialize the socket
                this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl] != null)
                {
                    this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl]);
                }

                // Receive buffer size
                this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpReceiveBuffer]);
                this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);

                this._socket.Bind(ipEndPoint);

                // if it's an IP multicast sender
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpMulticastTo] != null)
                {
                    try
                    {
                        url = (string)this.ITransportContext.IParameterProvider[GenuineParameter.UdpMulticastTo];
                        url = GenuineUtility.SplitToHostAndPort(url, out port);
                        this._multicastTo = new IPEndPoint(GenuineUtility.ResolveIPAddress(url), port);

                        this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                        if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl] != null)
                        {
                            this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, (int)this.ITransportContext.IParameterProvider[GenuineParameter.UdpTtl]);
                        }
                    }
                    catch (Exception)
                    {
                        throw GenuineExceptions.Get_Channel_InvalidParameter("UdpMulticastTo");
                    }
                }

                // and join to the specified broadcast network
                if (this.ITransportContext.IParameterProvider[GenuineParameter.UdpJoinTo] != null)
                {
                    string joinTo = (string)this.ITransportContext.IParameterProvider[GenuineParameter.UdpJoinTo];
                    this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

                    IPAddress       ipAddressToJoinTo = GenuineUtility.ResolveIPAddress(joinTo);
                    MulticastOption multicastOption   = new MulticastOption(ipAddressToJoinTo, ipEndPoint.Address);
                    this._socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multicastOption);
                }

                // initiate receiving
                Thread receivingThread = new Thread(new ThreadStart(this.ReceiveSynchronously));
                receivingThread.IsBackground = true;
                receivingThread.Start();

                // LOG:
                if (binaryLogWriter != null && binaryLogWriter[LogCategory.Connection] > 0)
                {
                    binaryLogWriter.WriteEvent(LogCategory.Connection, "UdpConnectionManager.StartListening",
                                               LogMessageType.ConnectionEstablished, null, null, null, null,
                                               GenuineUtility.CurrentThreadId, Thread.CurrentThread.Name,
                                               null, null,
                                               this.DbgConnectionId, (int)GenuineConnectionType.Invocation, 0, 0, this.GetType().Name, this._socket.LocalEndPoint.ToString(), null, null,
                                               "The UDP socket is ready for action.");
                }
            }
        }
Пример #16
0
 internal static extern unsafe Error SetIPv6MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv6MulticastOption *option);
Пример #17
0
        /// <summary>
        /// Sets multicast socket options.
        /// </summary>
        /// <param name="option">Option to set.</param>
        /// <param name="value">Value to set the option to.</param>
        public void SetOption( MulticastOption option, long value )
        {
            Contract.Requires( !Disposed );
            Contract.Requires( option == MulticastOption.DataRate
                            || option == MulticastOption.RecoveryInterval
                            || option == MulticastOption.RecoveryIntervalMS
                            || option == MulticastOption.Loopback );

            if( C.zmq_setsockopt( m_sock, (int)option, ref value, new C.size_t( Marshal.SizeOf( value ) ) ) != 0 )
            {
                throw ZeroMQException.CurrentError();
            }
        }
Пример #18
0
        /// <summary>
        /// Start listening for incoming messages on the specified port and network interface.
        /// </summary>

        public bool Start(int port, IPAddress ni)
        {
            Stop();

            mPort   = port;
            mSocket = new Socket(ni.AddressFamily, SocketType.Dgram, ProtocolType.Udp);

#if !UNITY_WEBPLAYER
            // Web player doesn't seem to support broadcasts
            mSocket.MulticastLoopback = true;
            mMulticast = useMulticasting;

            try
            {
                if (useMulticasting)
                {
                    List <IPAddress> ips = Tools.localAddresses;

                    foreach (IPAddress ip in ips)
                    {
                        MulticastOption opt = new MulticastOption(multicastIP, ip);
                        mSocket.SetSocketOption(ni.AddressFamily == AddressFamily.InterNetworkV6 ?
                                                SocketOptionLevel.IPv6 : SocketOptionLevel.IP, SocketOptionName.AddMembership, opt);
                    }
                }
                else
                {
                    mSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
                }
            }
            catch (System.Exception) { }
#endif
            // Port zero means we will be able to send, but not receive
            if (mPort == 0)
            {
                return(true);
            }

            try
            {
                // Use the default network interface if one wasn't explicitly chosen
 #if (UNITY_IPHONE && !UNITY_EDITOR) //|| UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX
                IPAddress networkInterface = useMulticasting ? multicastIP : ni;
#else
                IPAddress networkInterface = ni;
 #endif
                mEndPoint        = new IPEndPoint(networkInterface, 0);
                mDefaultEndPoint = new IPEndPoint(networkInterface, 0);

                // Bind the socket to the specific network interface and start listening for incoming packets
                mSocket.Bind(new IPEndPoint(networkInterface, mPort));
                mSocket.BeginReceiveFrom(mTemp, 0, mTemp.Length, SocketFlags.None, ref mEndPoint, OnReceive, null);
            }
#if UNITY_EDITOR
            catch (System.Exception ex)
            {
                UnityEngine.Debug.LogError("[TNet] Udp.Start: " + ex.Message);
                Stop();
                return(false);
            }
#elif DEBUG
            catch (System.Exception ex) { Tools.Print("Udp.Start: " + ex.Message); Stop(); return(false); }
#else
            catch (System.Exception) { Stop(); return(false); }
#endif
            return(true);
        }
Пример #19
0
 internal static extern unsafe Error GetIPv6MulticastOption(SafeHandle socket, MulticastOption multicastOption, IPv6MulticastOption* option);
Пример #20
0
        Task ListenForAnnouncementsAsync(System.Net.NetworkInformation.NetworkInterface adapter, Action <AdapterInformation, string, byte[]> callback, CancellationToken cancellationToken)
        {
            return(Task.Factory.StartNew(async() =>
            {
                var ipv4Address = adapter.GetIPProperties().UnicastAddresses
                                  .First(ua => ua.Address.AddressFamily == AddressFamily.InterNetwork)?.Address;

                if (ipv4Address == null)
                {
                    return;
                }

                var ifaceIndex = adapter.GetIPProperties().GetIPv4Properties()?.Index;
                if (ifaceIndex == null)
                {
                    return;
                }

                Debug.WriteLine($"Scanning on iface {adapter.Name}, idx {ifaceIndex}, IP: {ipv4Address}");

                using (var client = new UdpClient())
                {
                    var socket = client.Client;
                    socket.SetSocketOption(SocketOptionLevel.IP,
                                           SocketOptionName.MulticastInterface,
                                           IPAddress.HostToNetworkOrder(ifaceIndex.Value));

                    socket.SetSocketOption(SocketOptionLevel.Socket,
                                           SocketOptionName.ReuseAddress,
                                           true);
                    client.ExclusiveAddressUse = false;


                    var localEp = new IPEndPoint(IPAddress.Any, 5353);
                    socket.Bind(localEp);

                    var multicastAddress = IPAddress.Parse("224.0.0.251");
                    var multOpt = new MulticastOption(multicastAddress, ifaceIndex.Value);
                    socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);


                    cancellationToken.Register((() =>
                    {
                        ((IDisposable)client).Dispose();
                    }));


                    while (!cancellationToken.IsCancellationRequested)
                    {
                        try
                        {
                            var packet = await client.ReceiveAsync()
                                         .ConfigureAwait(false);
                            try
                            {
                                callback(new AdapterInformation(ipv4Address.ToString(), adapter.Name), packet.RemoteEndPoint.Address.ToString(), packet.Buffer);
                            }
                            catch (Exception ex)
                            {
                                Debug.WriteLine($"Callback threw an exception: {ex}");
                            }
                        }
                        catch when(cancellationToken.IsCancellationRequested)
                        {
                            // eat any exceptions if we've been cancelled
                        }
                    }


                    Debug.WriteLine($"Done listening for mDNS packets on {adapter.Name}, idx {ifaceIndex}, IP: {ipv4Address}.");

                    cancellationToken.ThrowIfCancellationRequested();
                }
            }, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default).Unwrap());
        }
Пример #21
0
 internal static extern unsafe Error SetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption* option);
Пример #22
0
        async Task NetworkRequestAsync(byte[] requestBytes,
                                       TimeSpan scanTime,
                                       int retries,
                                       int retryDelayMilliseconds,
                                       Action <IPAddress, byte[]> onResponse,
                                       System.Net.NetworkInformation.NetworkInterface adapter,
                                       CancellationToken cancellationToken)
        {
            // http://stackoverflow.com/questions/2192548/specifying-what-network-interface-an-udp-multicast-should-go-to-in-net

            // Xamarin doesn't support this
            //if (!adapter.GetIPProperties().MulticastAddresses.Any())
            //    return; // most of VPN adapters will be skipped

            if (!adapter.SupportsMulticast)
            {
                return; // multicast is meaningless for this type of connection
            }
            if (OperationalStatus.Up != adapter.OperationalStatus)
            {
                return; // this adapter is off or not connected
            }
            if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            {
                return; // strip out loopback addresses
            }
            var p = adapter.GetIPProperties().GetIPv4Properties();

            if (null == p)
            {
                return; // IPv4 is not configured on this adapter
            }
            var ipv4Address = adapter.GetIPProperties().UnicastAddresses
                              .FirstOrDefault(ua => ua.Address.AddressFamily == AddressFamily.InterNetwork)?.Address;

            if (ipv4Address == null)
            {
                return; // could not find an IPv4 address for this adapter
            }
            var ifaceIndex = p.Index;

            Debug.WriteLine($"Scanning on iface {adapter.Name}, idx {ifaceIndex}, IP: {ipv4Address}");


            using (var client = new UdpClient())
            {
                for (var i = 0; i < retries; i++)
                {
                    try
                    {
                        var socket = client.Client;

                        if (socket.IsBound)
                        {
                            continue;
                        }

                        socket.SetSocketOption(SocketOptionLevel.IP,
                                               SocketOptionName.MulticastInterface,
                                               IPAddress.HostToNetworkOrder(ifaceIndex));



                        client.ExclusiveAddressUse = false;
                        socket.SetSocketOption(SocketOptionLevel.Socket,
                                               SocketOptionName.ReuseAddress,
                                               true);
                        socket.SetSocketOption(SocketOptionLevel.Socket,
                                               SocketOptionName.ReceiveTimeout,
                                               (int)scanTime.TotalMilliseconds);
                        client.ExclusiveAddressUse = false;


                        var multicastAddress = IPAddress.Parse("224.0.0.251");
                        var multOpt          = new MulticastOption(multicastAddress, ifaceIndex);
                        socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, multOpt);

                        if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                        {
                            var localEp = new IPEndPoint(IPAddress.Any, 5353);
                            Debug.WriteLine($"Attempting to bind to {localEp} on adapter {adapter.Name}");
                            socket.Bind(localEp);
                            Debug.WriteLine($"Bound to {localEp}");
                            Debug.WriteLine("Bound to multicast address");
                        }

                        // Start a receive loop
                        var shouldCancel = false;
                        var recTask      = Task.Run(async
                                                        () =>
                        {
                            try
                            {
                                while (!Volatile.Read(ref shouldCancel))
                                {
                                    var res = await client.ReceiveAsync()
                                              .ConfigureAwait(false);

                                    if (res.RemoteEndPoint != null && res.Buffer != null && res.RemoteEndPoint.Port == 5353)
                                    {
                                        onResponse(res.RemoteEndPoint.Address, res.Buffer);
                                    }
                                }
                            }
                            catch when(Volatile.Read(ref shouldCancel))
                            {
                                // If we're canceling, eat any exceptions that come from here
                            }
                        }, cancellationToken);

                        var broadcastEp = new IPEndPoint(IPAddress.Parse("224.0.0.251"), 5353);

                        Debug.WriteLine($"About to send on iface {adapter.Name}");
                        await client.SendAsync(requestBytes, requestBytes.Length, broadcastEp)
                        .ConfigureAwait(false);

                        Debug.WriteLine($"Sent mDNS query on iface {adapter.Name}");


                        // wait for responses
                        await Task.Delay(scanTime, cancellationToken)
                        .ConfigureAwait(false);

                        Volatile.Write(ref shouldCancel, true);

                        ((IDisposable)client).Dispose();

                        Debug.WriteLine("Done Scanning");


                        await recTask.ConfigureAwait(false);

                        return;
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine($"Execption with network request, IP {ipv4Address}\n: {e}");
                        if (i + 1 >= retries) // last one, pass underlying out
                        {
                            // Ensure all inner info is captured
                            ExceptionDispatchInfo.Capture(e).Throw();
                            throw;
                        }
                    }

                    await Task.Delay(retryDelayMilliseconds, cancellationToken).ConfigureAwait(false);
                }
            }
        }
Пример #23
0
 private static extern unsafe Error DangerousSetIPv6MulticastOption(int socket, MulticastOption multicastOption, IPv6MulticastOption* option);
Пример #24
0
        // This thread handles incoming NatNet packets.
        private void ThreadRun()
        {
            stopReceive = false;
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            ipEndPoint = new IPEndPoint(IPAddress.Any, BLACK_BOX_CLIENT_PORT);
            //Debug.Log("prebind");
            socket.Bind(ipEndPoint);
            //Debug.Log("bind");
            MulticastOption mo = new MulticastOption(IPAddress.Parse("224.1.1.1"));

            socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, mo);

            nBytesReceived     = 0;
            lastLoadedBuffer   = b1;
            lastLoadedBufferMS = b1ms;
            lastLoadedFrame    = 0;

            byte[]       newPacketBuffer   = b2;
            MemoryStream newPacketBufferMS = b2ms;
            long         newPacketFrame    = 0;

            byte[]       tempBuffer;
            MemoryStream tempBufferMS;

            while (true)
            {
                //Debug.Log("preRECV");
                nBytesReceived = socket.Receive(newPacketBuffer);
                //Debug.Log("RECV");
                nPackets++;
                newPacketBufferMS.Position = 0;

                update_protocol_v3.Update update = Serializer.Deserialize <update_protocol_v3.Update>(new MemoryStream(newPacketBuffer, 0, nBytesReceived));
                //Debug.Log ("received update of type " + update.id);

                newPacketFrame = update.mod_version;

                if (newPacketFrame > lastLoadedFrame)
                {
                    // Swap the buffers and reset the positions.
                    lastLoadedBufferMS.Position = 0;
                    newPacketBufferMS.Position  = 0;
                    tempBuffer         = lastLoadedBuffer;
                    tempBufferMS       = lastLoadedBufferMS;
                    lastLoadedBuffer   = newPacketBuffer;
                    lastLoadedBufferMS = newPacketBufferMS;
                    newPacketBuffer    = tempBuffer;
                    newPacketBufferMS  = tempBufferMS;
                    lastLoadedFrame    = newPacketFrame;



                    for (int j = 0; j < update.live_objects.Count; j++)
                    {
                        LiveObject        or    = update.live_objects[j];
                        string            label = or.label;
                        LiveObjectStorage ow;
                        lock (lock_object) {
                            if (!labelToLiveObject.TryGetValue(label, out ow))
                            {
                                ow = new LiveObjectStorage();
                                labelToLiveObject[label] = ow;
                            }
                            else
                            {
                                ow = labelToLiveObject[label];
                            }
                            if (update.lhs_frame)
                            {
                                ow.pos = new Vector3(-(float)or.x, (float)or.y, (float)or.z);
                                ow.rot = new Quaternion(-(float)or.qx, (float)or.qy, (float)or.qz, -(float)or.qw);
                            }
                            else
                            {
                                ow.pos = new Vector3((float)or.x, (float)or.y, (float)or.z);
                                ow.rot = new Quaternion((float)or.qx, (float)or.qy, (float)or.qz, (float)or.qw);
                            }
                            //Debug.Log (label + " positon: " + ow.pos);
                            //Debug.Log (label + " rotation: " + ow.rot);
                            if (or.button_bits > 0)
                            {
                                ow.button_bits = or.button_bits;
                            }
                        }
                    }
                }
                if (stopReceive)
                {
                    break;
                }
            }
        }