public bool SendDiscoveryResponse(byte[] data, NetEndPoint remoteEndPoint)
 {
     return(SendDiscoveryResponse(data, 0, data.Length, remoteEndPoint));
 }
Beispiel #2
0
        public bool Bind(int port, bool reuseAddress)
        {
            _udpSocketv4                   = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            _udpSocketv4.Blocking          = false;
            _udpSocketv4.ReceiveBufferSize = NetConstants.SocketBufferSize;
            _udpSocketv4.SendBufferSize    = NetConstants.SocketBufferSize;
            _udpSocketv4.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.IpTimeToLive, NetConstants.SocketTTL);
            if (reuseAddress)
            {
                _udpSocketv4.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            }
#if !NETCORE
            _udpSocketv4.DontFragment = true;
#endif

            try
            {
                _udpSocketv4.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            }
            catch (SocketException e)
            {
                NetUtils.DebugWriteError("Broadcast error: {0}", e.ToString());
            }

            if (!BindSocket(_udpSocketv4, new IPEndPoint(IPAddress.Any, port)))
            {
                return(false);
            }
            _localEndPoint = new NetEndPoint((IPEndPoint)_udpSocketv4.LocalEndPoint);

            _running               = true;
            _threadv4              = new Thread(ReceiveLogic);
            _threadv4.Name         = "SocketThreadv4(" + port + ")";
            _threadv4.IsBackground = true;
            _threadv4.Start(_udpSocketv4);

            //Check IPv6 support
            if (!IPv6Support)
            {
                return(true);
            }

            //Use one port for two sockets
            port = _localEndPoint.Port;

            _udpSocketv6                   = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
            _udpSocketv6.Blocking          = false;
            _udpSocketv6.ReceiveBufferSize = NetConstants.SocketBufferSize;
            _udpSocketv6.SendBufferSize    = NetConstants.SocketBufferSize;
            if (reuseAddress)
            {
                _udpSocketv6.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            }

            if (BindSocket(_udpSocketv6, new IPEndPoint(IPAddress.IPv6Any, port)))
            {
                _localEndPoint = new NetEndPoint((IPEndPoint)_udpSocketv6.LocalEndPoint);

                try
                {
                    _udpSocketv6.SetSocketOption(
                        SocketOptionLevel.IPv6,
                        SocketOptionName.AddMembership,
                        new IPv6MulticastOption(MulticastAddressV6));
                }
                catch (Exception)
                {
                    // Unity3d throws exception - ignored
                }

                _threadv6              = new Thread(ReceiveLogic);
                _threadv6.Name         = "SocketThreadv6(" + port + ")";
                _threadv6.IsBackground = true;
                _threadv6.Start(_udpSocketv6);
            }

            return(true);
        }
 /// <summary>
 /// Send message without connection
 /// </summary>
 /// <param name="writer">Data serializer</param>
 /// <param name="remoteEndPoint">Packet destination</param>
 /// <returns>Operation result</returns>
 public bool SendUnconnectedMessage(NetDataWriter writer, NetEndPoint remoteEndPoint)
 {
     return(SendUnconnectedMessage(writer.Data, 0, writer.Length, remoteEndPoint));
 }
 public bool SendDiscoveryResponse(NetDataWriter writer, NetEndPoint remoteEndPoint)
 {
     return(SendDiscoveryResponse(writer.Data, 0, writer.Length, remoteEndPoint));
 }
 /// <summary>
 /// Send message without connection
 /// </summary>
 /// <param name="message">Raw data</param>
 /// <param name="remoteEndPoint">Packet destination</param>
 /// <returns>Operation result</returns>
 public bool SendUnconnectedMessage(byte[] message, NetEndPoint remoteEndPoint)
 {
     return(SendUnconnectedMessage(message, 0, message.Length, remoteEndPoint));
 }
        private void DataReceived(byte[] reusableBuffer, int count, NetEndPoint remoteEndPoint)
        {
#if STATS_ENABLED
            PacketsReceived++;
            BytesReceived += (uint)count;
#endif

            //Try read packet
            NetPacket packet = _netPacketPool.GetAndRead(reusableBuffer, 0, count);
            if (packet == null)
            {
                NetUtils.DebugWriteError("[NM] DataReceived: bad!");
                return;
            }

            //Check unconnected
            switch (packet.Property)
            {
            case PacketProperty.DiscoveryRequest:
                if (DiscoveryEnabled)
                {
                    var netEvent = CreateEvent(NetEventType.DiscoveryRequest);
                    netEvent.RemoteEndPoint = remoteEndPoint;
                    netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize);
                    EnqueueEvent(netEvent);
                }
                return;

            case PacketProperty.DiscoveryResponse:
            {
                var netEvent = CreateEvent(NetEventType.DiscoveryResponse);
                netEvent.RemoteEndPoint = remoteEndPoint;
                netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize);
                EnqueueEvent(netEvent);
            }
                return;

            case PacketProperty.UnconnectedMessage:
                if (UnconnectedMessagesEnabled)
                {
                    var netEvent = CreateEvent(NetEventType.ReceiveUnconnected);
                    netEvent.RemoteEndPoint = remoteEndPoint;
                    netEvent.DataReader.SetSource(packet.RawData, NetConstants.HeaderSize);
                    EnqueueEvent(netEvent);
                }
                return;

            case PacketProperty.NatIntroduction:
            case PacketProperty.NatIntroductionRequest:
            case PacketProperty.NatPunchMessage:
            {
                if (NatPunchEnabled)
                {
                    NatPunchModule.ProcessMessage(remoteEndPoint, packet);
                }
                return;
            }
            }

            //Check normal packets
            NetPeer netPeer;

            //Check peers
            Monitor.Enter(_peers);
            int peersCount = _peers.Count;

            if (_peers.TryGetValue(remoteEndPoint, out netPeer))
            {
                Monitor.Exit(_peers);
                //Send
                if (packet.Property == PacketProperty.Disconnect)
                {
                    if (BitConverter.ToInt64(packet.RawData, 1) != netPeer.ConnectId)
                    {
                        //Old or incorrect disconnect
                        _netPacketPool.Recycle(packet);
                        return;
                    }

                    var netEvent = CreateEvent(NetEventType.Disconnect);
                    netEvent.Peer = netPeer;
                    netEvent.DataReader.SetSource(packet.RawData, 5, packet.Size - 5);
                    netEvent.DisconnectReason = DisconnectReason.RemoteConnectionClose;
                    EnqueueEvent(netEvent);

                    _peers.Remove(netPeer.EndPoint);
                    //do not recycle because no sense)
                }
                else if (packet.Property == PacketProperty.ConnectAccept)
                {
                    if (netPeer.ProcessConnectAccept(packet))
                    {
                        var connectEvent = CreateEvent(NetEventType.Connect);
                        connectEvent.Peer = netPeer;
                        EnqueueEvent(connectEvent);
                    }
                    _netPacketPool.Recycle(packet);
                }
                else
                {
                    netPeer.ProcessPacket(packet);
                }
                return;
            }

            try
            {
                if (peersCount < _maxConnections && packet.Property == PacketProperty.ConnectRequest)
                {
                    int protoId = BitConverter.ToInt32(packet.RawData, 1);
                    if (protoId != NetConstants.ProtocolId)
                    {
                        NetUtils.DebugWrite(ConsoleColor.Cyan,
                                            "[NM] Peer connect reject. Invalid protocol ID: " + protoId);
                        return;
                    }

                    string peerKey = Encoding.UTF8.GetString(packet.RawData, 13, packet.Size - 13);
                    if (peerKey != _connectKey)
                    {
                        NetUtils.DebugWrite(ConsoleColor.Cyan, "[NM] Peer connect reject. Invalid key: " + peerKey);
                        return;
                    }

                    //Getting new id for peer
                    long connectionId = BitConverter.ToInt64(packet.RawData, 5);
                    //response with id
                    netPeer = new NetPeer(this, remoteEndPoint, connectionId);
                    NetUtils.DebugWrite(ConsoleColor.Cyan, "[NM] Received peer connect request Id: {0}, EP: {1}",
                                        netPeer.ConnectId, remoteEndPoint);

                    //clean incoming packet
                    _netPacketPool.Recycle(packet);

                    _peers.Add(remoteEndPoint, netPeer);

                    var netEvent = CreateEvent(NetEventType.Connect);
                    netEvent.Peer = netPeer;
                    EnqueueEvent(netEvent);
                }
            }
            finally
            {
                Monitor.Exit(_peers);
            }
        }
Beispiel #7
0
 public bool ContainsAddress(NetEndPoint endPoint)
 {
     return(_peersDict.ContainsKey(endPoint));
 }
Beispiel #8
0
 public void Add(NetEndPoint endPoint, NetPeer peer)
 {
     _peersArray[_count] = peer;
     _peersDict.Add(endPoint, peer);
     _count++;
 }
Beispiel #9
0
 public bool TryGetValue(NetEndPoint endPoint, out NetPeer peer)
 {
     return(_peersDict.TryGetValue(endPoint, out peer));
 }