Exemplo n.º 1
0
        /// <summary>
        /// Create a message receiver server which can accept connection from many clients
        /// </summary>
        /// <param name="port"></param>
        /// <param name="protocol"></param>
        public MessageReceiver(int port, NetworkProtocolType protocol)
        {
            if (port <= 0)
            {
                throw new ArgumentException("port must be > 0");
            }

            if (protocol != NetworkProtocolType.TCP)
            {
                throw new NotSupportedException(String.Format("This protocol {0} is currently not supported", protocol));
            }

            Port = port;

            using (Barrier untilStartedListening = new Barrier(2))
            {
                Listener           = new TcpListener(IPAddress.Any, Port);
                CancelSource       = new CancellationTokenSource();
                CancelToken        = CancelSource.Token;
                ConnectionAcceptor = Task.Factory.StartNew(() => StartAcceptingConnections(untilStartedListening), CancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
                if (untilStartedListening.SignalAndWait(5000) == false)
                {
                    throw new InvalidOperationException($"Could not start network receiver on port {Port}. LastStartException: {LastStartException}");
                }
            }
        }
Exemplo n.º 2
0
        public string GetEndPoint(NetworkProtocolType networkProtocolType, int port, bool isIPv6 = false, bool useHostnames = false)
        {
            switch (networkProtocolType)
            {
            default:
                throw new NotSupportedException("No Master server endpoint configured for network protocol " + networkProtocolType);

            case NetworkProtocolType.Udp:
                return(useHostnames ? this.UdpHostname :  (isIPv6 ? this.UdpIPv6EndPoint : this.UdpEndPoint));

            case NetworkProtocolType.Tcp:
                return(useHostnames ? this.TcpHostname :  (isIPv6 ? this.TcpIPv6EndPoint : this.TcpEndPoint));

            case NetworkProtocolType.WebSocket:
                return(isIPv6 ? this.WebSocketIPv6EndPoint : this.WebSocketEndPoint);

            case NetworkProtocolType.SecureWebSocket:
                return(isIPv6 ? this.SecureWebSocketIPv6EndPoint : this.SecureWebSocketEndPoint);

            case NetworkProtocolType.Http:
                if (port == 443)
                {
                    return(isIPv6 ? this.SecureHttpIPv6EndPoint : this.SecureHttpEndPoint);
                }
                return(isIPv6 ? this.HttpIPv6EndPoint : this.HttpEndPoint);

            case NetworkProtocolType.WebRTC:
                //TODO
//                    return "192.168.78.204:7071";
                return(this.WebRTCEndPoint);
            }
        }
 private static NetworkProtocol CreateNetworkProtocol(NetworkProtocolType protocolType, string ports, bool enabled)
 {
     return new NetworkProtocol() {
         name = protocolType,
         port = ports == null ? null : ports.Split(new[] { ';', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => Int32.Parse(p)).ToArray(),
         enabled = enabled
     };
 }
Exemplo n.º 4
0
        public bool SupportsProtocol(NetworkProtocolType networkProtocol)
        {
            if (this.gameServerContext == null)
            {
                return(false);
            }

            if (this.gameServerContext.SupportedProtocols == null)
            {
                return(true);
            }

            return(this.gameServerContext.SupportedProtocols.Contains((byte)networkProtocol));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Create a connection to a remove machine to send data to it.
        /// </summary>
        /// <param name="host">Hostname</param>
        /// <param name="port">Port</param>
        /// <param name="protocol">Protocol. Currently only TCP is supported</param>
        /// <exception cref="ArgumentException">When host is null or empty or the port number is 0 or negative.</exception>
        /// <exception cref="NotSupportedException">When another protocol than TCP is used.</exception>
        /// <exception cref="SocketException">Server does not exist or it refused the connection because no server is running on that port.</exception>
        public MessageSender(string host, int port, NetworkProtocolType protocol)
        {
            if (String.IsNullOrEmpty(host))
            {
                throw new ArgumentException("host is null or empty");
            }

            if (port <= 0)
            {
                throw new ArgumentException("port must be > 0");
            }

            if (protocol != NetworkProtocolType.TCP)
            {
                throw new NotSupportedException(String.Format("This protocol {0} is currently not supported", protocol));
            }

            Host     = host;
            Port     = port;
            Protocol = protocol;

            RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port);

            if (protocol == NetworkProtocolType.TCP)
            {
                const int Retries = 2;

                // Try to connect to server with 2 retries and a short sleep in between
                for (int i = 0; i < Retries; i++)
                {
                    try
                    {
                        Client = new TcpClient(Host, Port);
                        ConfigureSocket(Client.Client);
                        this.NetworkSend = Client.GetStream();
                        break;
                    }
                    catch (SocketException)
                    {
                        if (i == Retries - 1)
                        {
                            throw;
                        }
                        Thread.Sleep(10);
                    }
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Mapping"/> class.
        /// </summary>
        /// <param name="networkProtocolType">The protocol.</param>
        /// <param name="privateIP">The private ip.</param>
        /// <param name="privatePort">The private port.</param>
        /// <param name="publicPort">The public port.</param>
        /// <param name="lifetime">The lifetime.</param>
        /// <param name="description">The description.</param>
        public Mapping(NetworkProtocolType networkProtocolType, IPAddress privateIP, int privatePort, int publicPort, int lifetime, string description)
        {
            Guard.IsInRange(privatePort, 0, ushort.MaxValue, "privatePort");
            Guard.IsInRange(publicPort, 0, ushort.MaxValue, "publicPort");
            Guard.IsInRange(lifetime, 0, int.MaxValue, "lifetime");
            Guard.IsTrue(networkProtocolType == NetworkProtocolType.Tcp || networkProtocolType == NetworkProtocolType.Udp, "protocol");
            Guard.IsNotNull(privateIP, "privateIP");

            NetworkProtocolType = networkProtocolType;
            PrivateIP           = privateIP;
            PrivatePort         = privatePort;
            PublicIP            = IPAddress.None;
            PublicPort          = publicPort;
            Lifetime            = lifetime;
            Description         = description;
        }
Exemplo n.º 7
0
        public override async Task <Mapping> GetSpecificMappingAsync(NetworkProtocolType networkProtocolType, int publicPort)
        {
            Guard.IsTrue(networkProtocolType == NetworkProtocolType.Tcp || networkProtocolType == NetworkProtocolType.Udp, "protocol");
            Guard.IsInRange(publicPort, 0, ushort.MaxValue, "port");

            NatDiscoverer.TraceSource.LogInfo("GetSpecificMappingAsync - Getting mapping for protocol: {0} port: {1}", Enum.GetName(typeof(NetworkProtocolType), networkProtocolType), publicPort);

            try
            {
                var message      = new GetSpecificPortMappingEntryRequestMessage(networkProtocolType, publicPort);
                var responseData = await _soapClient
                                   .InvokeAsync("GetSpecificPortMappingEntry", message.ToXml())
                                   .TimeoutAfter(TimeSpan.FromSeconds(4));

                var messageResponse = new GetPortMappingEntryResponseMessage(responseData, DeviceInfo.ServiceType, false);

                if (messageResponse.NetworkProtocolType != networkProtocolType)
                {
                    NatDiscoverer.TraceSource.LogWarn("Router responded to a protocol {0} query with a protocol {1} answer, work around applied.", networkProtocolType, messageResponse.NetworkProtocolType);
                }

                return(new Mapping(networkProtocolType
                                   , IPAddress.Parse(messageResponse.InternalClient)
                                   , messageResponse.InternalPort
                                   , publicPort      // messageResponse.ExternalPort is short.MaxValue
                                   , messageResponse.LeaseDuration
                                   , messageResponse.PortMappingDescription));
            }
            catch (MappingException e)
            {
                // there are no more mappings
                if (e.ErrorCode == UpnpConstants.SpecifiedArrayIndexInvalid ||
                    e.ErrorCode == UpnpConstants.NoSuchEntryInArray
                    // DD-WRT Linux base router (and others probably) fails with 402-InvalidArgument when index is out of range
                    || e.ErrorCode == UpnpConstants.InvalidArguments
                    // LINKSYS WRT1900AC AC1900 it returns errocode 501-PAL_UPNP_SOAP_E_ACTION_FAILED
                    || e.ErrorCode == UpnpConstants.ActionFailed)
                {
                    NatDiscoverer.TraceSource.LogWarn("Router failed with {0}-{1}. No more mappings is assumed.", e.ErrorCode, e.ErrorText);
                    return(null);
                }
                throw;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// 与远程建立连接;
        /// 当前只有udp
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <param name="port">端口号</param>
        /// <param name="protocolType">协议类型</param>
        public void Connect(ushort port, NetworkProtocolType protocolType = NetworkProtocolType.KCP)
        {
            OnUnPause();
            currentNetworkProtocolType = protocolType;
            switch (protocolType)
            {
            case NetworkProtocolType.KCP:
            {
                var kcpServer = new KcpServerService();
                kcpServerService      = kcpServer;
                KCPLog.Info           = (s) => Utility.Debug.LogInfo(s);
                KCPLog.Warning        = (s) => Utility.Debug.LogWarning(s);
                KCPLog.Error          = (s) => Utility.Debug.LogError(s);
                kcpServerService.Port = (ushort)port;
                kcpServerService.ServiceSetup();
                kcpServerService.ServiceUnpause();
                kcpServerService.OnServerDataReceived += OnKCPReceiveDataHandler;
                kcpServerService.OnServerDisconnected += OnDisconnectedHandler;
                kcpServerService.OnServerConnected    += OnConnectedHandler;
                kcpServerService.ServiceConnect();
            }
            break;

            case NetworkProtocolType.TCP:
            {
            }
            break;

            case NetworkProtocolType.UDP:
            {
                //service = new UdpServerService();
                //UdpServerService udp = service as UdpServerService;
                //udp.OnReceiveData += OnReceiveDataHandler;
                //udp.OnConnected+= OnConnectedHandler;
                //udp.OnDisconnected+= OnDisconnectedHandler;
                //udp.Port = port;
                //service.OnInitialization();
            }
            break;
            }
        }
        public bool TryGetRegions(GetRegionListRequest regionListRequest, NetworkProtocolType networkProtocol,
                                  int port, bool isIPv6, bool useHostnames,
                                  out List <string> regions, out List <string> endPoints, out string message)
        {
            regions   = new List <string>();
            endPoints = new List <string>();
            message   = string.Empty;

            foreach (var server in this.servers)
            {
                var endpoint = server.GetEndPoint(networkProtocol, port, isIPv6, useHostnames);
                if (endpoint == null)
                {
                    continue;
                }

                regions.Add(server.Region);
                endPoints.Add(endpoint);
            }

            return(true);
        }
        protected virtual OperationResponse HandleAuthenticateRequest(AuthenticateRequest authenticateRequest,
                                                                      SendParameters sendParameters, NetworkProtocolType endpointProtocol)
        {
            if (authenticateRequest.IsValid == false)
            {
                this.HandleInvalidOperation(authenticateRequest, sendParameters);
                return(null);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Got Auth Request:appId={0};version={1};region={2};type={3};userId={4}",
                                authenticateRequest.ApplicationId,
                                authenticateRequest.ApplicationVersion,
                                authenticateRequest.Region,
                                authenticateRequest.ClientAuthenticationType,
                                authenticateRequest.UserId);
            }

            if (!string.IsNullOrEmpty(this.authenticatedApplicationId))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "Authenticate called twice: already authenticated with appId={5}. Will handle new AuthRequest: appId={0};version={1};region={2};type={3};userId={4}",
                        authenticateRequest.ApplicationId,
                        authenticateRequest.ApplicationVersion,
                        authenticateRequest.Region,
                        authenticateRequest.ClientAuthenticationType,
                        authenticateRequest.UserId,
                        this.authenticatedApplicationId);
                }
            }


            /////
            if (this.Connected == false)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("OnGetApplicationAccount: Client disconnected. Ignore response.");
                }
                return(null);
            }

            var operationRequest = authenticateRequest.OperationRequest;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat(
                    "HandleAuthenticateRequest for App ID {0}",
                    authenticateRequest.ApplicationId);
            }

            // store for debugging purposes.
            this.authenticatedApplicationId = authenticateRequest.ApplicationId;

            // try to get the master server instance for the specified application id
            PhotonEndpointInfo masterServer;
            string             message;

            if (!this.application.ServerCache.TryGetPhotonEndpoint(authenticateRequest.Region, out masterServer, out message))
            {
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("MasterServer not found for: {0}. AppId: {1}", message, authenticateRequest.ApplicationId);
                }
                //CHECK why only invalid region err?
                this.SendOperationResponse(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode = (short)ErrorCode.InvalidRegion,
                    //DebugMessage =
                    //    string.Format("Cloud {0} / Region {1} is not available.", applicationAccount.PrivateCloud, authenticateRequest.Region)
                }, sendParameters);
                return(null);
            }

            //TODO change
            string masterEndPoint;

            try
            {
                masterEndPoint = masterServer.GetEndPoint(endpointProtocol, this.LocalPort,
                                                          isIPv6: this.LocalIPAddressIsIPv6, useHostnames: this.IsIPv6ToIPv4Bridged);
            }
            catch (Exception e)
            {
                //webrtc
                masterEndPoint = masterServer.GetEndPoint(endpointProtocol, 0);

                var str = string.Format(
                    "Handle Auth: Exception during GetEndPoint call. EndPoint protocol:{0}, LocalPort:{1}, isIpV6:{2}, useHostNames:{3}",
                    endpointProtocol, this.LocalPort, this.LocalIPAddressIsIPv6, this.IsIPv6ToIPv4Bridged);

                log.Warn(exceptionGuard, str, e);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Endpoint found 1 - Hostname {0}, UDP: {1}, HTTP: {2}", masterServer.UdpHostname, masterServer.UdpEndPoint, masterServer.HttpEndPoint);
            }

            if (masterEndPoint == null)
            {
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat("Master server endpoint for protocol {0} not found on master server {1}.", this.NetworkProtocol, masterServer);
                }

                this.SendOperationResponse(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode   = (short)AuthErrorCode.ProtocolNotSupported,
                    DebugMessage = ErrorMessages.ProtocolNotSupported
                }, sendParameters);
                return(null);
            }

            ///
            // check if custom client authentication is required
            if (this.application.CustomAuthHandler.IsClientAuthenticationEnabled)
            {
                if (this.application.TokenCreator == null)
                {
                    log.WarnFormat("No custom authentication supported: AuthTokenKey not specified in config.");

                    var resp = new OperationResponse(authenticateRequest.OperationRequest.OperationCode)
                    {
                        ReturnCode   = (short)ErrorCode.InvalidAuthentication,
                        DebugMessage = ErrorMessages.AuthTokenTypeNotSupported
                    };
                    this.SendOperationResponse(resp, sendParameters);
                    return(null);
                }

                var authSettings = new AuthSettings
                {
                    IsAnonymousAccessAllowed = this.application.CustomAuthHandler.IsAnonymousAccessAllowed,
                };

                this.application.CustomAuthHandler.AuthenticateClient(this, authenticateRequest, authSettings, sendParameters, authSettings);
                return(null);
            }

            var response = this.HandleDefaultAuthenticateRequest(authenticateRequest, masterEndPoint, new AuthSettings()); //TODO Check

            this.SendOperationResponse(response, sendParameters);

            //authenticate application id
            return(null);
        }
Exemplo n.º 11
0
#pragma warning restore 4014

        private static async Task ForwardPortInternalAsync(ushort port, int milisecondsDelay, NetworkProtocolType networkProtocolType = NetworkProtocolType.Udp)
        {
            try
            {
                if (LastForwardedPort == port || UpnpFailed)
                {
                    return;
                }
                if (LastForwardedPort != 0)
                {
                    NatDiscoverer.ReleaseAll();
                }
                NatDiscoverer discoverer = new NatDiscoverer();
                NatDevice     device;
                using (CancellationTokenSource cts = new CancellationTokenSource(milisecondsDelay))
                {
                    device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp | PortMapper.Pmp, cts).ConfigureAwait(false);
                }

                ExternalIp = await device.GetExternalIPAsync();

                await device.CreatePortMapAsync(new Mapping(networkProtocolType, IPAddress.None, port, port, 0, ApplicationName)).ConfigureAwait(false);

                LastForwardedPort = port;
                Debug.Log($"Port {port.ToString()} forwarded successfully!");
            }
            catch (Exception ex)
            {
                //Debug.LogWarning($"UPnP failed!\n{ex.Message}\n{ex.StackTrace}");
                UpnpFailed = true;
            }
        }
Exemplo n.º 12
0
 public override Task <Mapping> GetSpecificMappingAsync(NetworkProtocolType networkProtocolType, int port)
 {
     throw new NotSupportedException("NAT-PMP does not specify a way to get a specific port map");
 }
Exemplo n.º 13
0
 private bool isCast(NetworkProtocolType type)
 {
     if (type == NetworkProtocolType.multicast || type == NetworkProtocolType.unicast || type == NetworkProtocolType.tcpBroadcast)
     {
         return true;
     }
     else
     {
         return false;
     }
 }
        protected override OperationResponse HandleAuthenticateRequest(AuthenticateRequest authenticateRequest,
                                                                       SendParameters sendParameters, NetworkProtocolType endpointProtocol)
        {
            if (!authenticateRequest.IsValid)
            {
                this.HandleInvalidOperation(authenticateRequest, sendParameters);
                return(null);
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("Got Auth Request:appId={0};version={1};region={2};type={3};userId={4}",
                                authenticateRequest.ApplicationId,
                                authenticateRequest.ApplicationVersion,
                                authenticateRequest.Region,
                                authenticateRequest.ClientAuthenticationType,
                                authenticateRequest.UserId);
            }

            if (!string.IsNullOrEmpty(this.authenticatedApplicationId))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat(
                        "Authenticate called twice: already authenticated with appId={5}. Will handle new AuthRequest: appId={0};version={1};region={2};type={3};userId={4}",
                        authenticateRequest.ApplicationId,
                        authenticateRequest.ApplicationVersion,
                        authenticateRequest.Region,
                        authenticateRequest.ClientAuthenticationType,
                        authenticateRequest.UserId,
                        this.authenticatedApplicationId);
                }
            }
            // checking appId correctness
            Guid guid;

            if (!Guid.TryParse(authenticateRequest.ApplicationId, out guid))
            {
                if (log.IsInfoEnabled)
                {
                    var appId = authenticateRequest.ApplicationId ?? string.Empty;

                    log.InfoFormat("Authentication of client failed: Wrong applicationId, AppId={0}",
                                   appId.Length > 50 ? appId.Substring(0, 50) + "..." : appId);
                }

                this.SendOperationResponse(new OperationResponse(authenticateRequest.OperationRequest.OperationCode)
                {
                    ReturnCode   = (short)ErrorCode.InvalidAuthentication,
                    DebugMessage = ErrorMessages.InvalidAppId
                }, sendParameters);

                this.ScheduleDisconnect(this.GetDisconnectTime());
                return(null);
            }

            this.InitExecutor(authenticateRequest.ApplicationId, authenticateRequest.ApplicationVersion);
            ((PhotonCloudApp)this.application).AuthenticationCache.GetAccount(authenticateRequest.ApplicationId, this.RequestFiber,
                                                                              account => this.OnGetApplicationAccount(account, authenticateRequest, sendParameters, endpointProtocol));

            // authenticate application id
            return(null);
        }
 public static void ForwardPort(ushort port, NetworkProtocolType networkProtocolType = NetworkProtocolType.Udp, int milisecondsDelay = 10000)
 {
     ForwardPortInternalAsync(port, milisecondsDelay, networkProtocolType);
 }
Exemplo n.º 16
0
        public void setNetworkProtocolType(NetworkProtocolType type)
        {
            int typeNumber = 0; ;
            switch (type)
            {
                case NetworkProtocolType.multicast: typeNumber=19;break;
                case NetworkProtocolType.tcp: typeNumber=17;break;
                case NetworkProtocolType.unicast: typeNumber=18;break;
                case NetworkProtocolType.tcpBroadcast: typeNumber=31;break;
            }

            Push(PlanckDBConstants.DISTRIBUTION_TYPE, PlanckDBConstants.INTEGER, typeNumber);
        }
Exemplo n.º 17
0
        public bool GetRegionList(GetRegionListRequest request, ApplicationAccount appAccount, NetworkProtocolType networkProtocol, int port, bool isIPv6, bool useHostnames,
                                  out List <string> regions, out List <string> endPoints, out string message)
        {
            regions   = new List <string>();
            endPoints = new List <string>();
            message   = null;

            // check submitted ID:
            Guid appId;

            if (!Guid.TryParse(request.ApplicationId, out appId))
            {
                message = string.Format("Invalid Application ID format: {0}", request.ApplicationId);
                if (log.IsDebugEnabled)
                {
                    log.Debug(message);
                    return(false);
                }
            }

            if (string.IsNullOrEmpty(appAccount.PrivateCloud))
            {
                message = string.Format("No private cloud set for applicaton ID {0} - can not get Master", request.ApplicationId);
                log.Error(message);
                return(false);
            }

            var privateCloud = appAccount.PrivateCloud;

            if (log.IsDebugEnabled)
            {
                log.DebugFormat("PrivateCloud: {0}", privateCloud);
                var infos = appAccount.RegionClusterInfos;
                if (infos == null)
                {
                    log.DebugFormat("RegionClusterInfos == null!");
                }
                else
                {
                    log.DebugFormat("RegionClusterInfos:");
                    foreach (var info in infos)
                    {
                        log.DebugFormat(info.Key);
                        foreach (var clusterInfo in info.Value)
                        {
                            log.DebugFormat("\t{0}", clusterInfo);
                        }
                    }
                }
            }

            var allPhotonEndpoints = this.GetAllPhotonEndpoints(privateCloud, appAccount.ServiceType, appAccount);

            //tmp for whitelist
            var allRegions   = new List <string>();
            var allEndPoints = new List <string>();

            foreach (var server in allPhotonEndpoints)
            {
                var endpoint = server.GetEndPoint(networkProtocol, port, isIPv6, useHostnames);
                if (endpoint == null)
                {
                    continue;
                }

                string regionCluster = FormatRegionCultureString(server, allPhotonEndpoints);

                //use regionwhite list
                if (!string.IsNullOrEmpty(appAccount.GetRegionsFilter))
                {
                    //store all in case whitelist leaves no result
                    allRegions.Add(regionCluster);
                    allEndPoints.Add(endpoint);

                    if (!IsRegionClusterWhitelisted(appAccount.GetRegionsFilter, server.Region, server.Cluster))
                    {
                        if (log.IsDebugEnabled)
                        {
                            log.DebugFormat("Whitelist does not contain regionCluster '{0}', skipping", regionCluster);
                        }
                        continue;
                    }
                }

                regions.Add(regionCluster);
                endPoints.Add(endpoint);

                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("RegionCluster: {0} -> Endpoint: {1}", regionCluster, endpoint);
                }
            }

            if (!string.IsNullOrEmpty(appAccount.GetRegionsFilter) && regions.Count == 0)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Whitelist left no entries, ignoring whitelist, returning all {0} entries", allRegions.Count);
                }
                regions.AddRange(allRegions);
                endPoints.AddRange(allEndPoints);
            }

            if (isIPv6 && regions.Count == 0)
            {
                message = string.Format("No IPv6 capable Master found for applicaton ID {0}", request.ApplicationId);
                log.Error(message);
                return(false);
            }

            return(true);
        }
Exemplo n.º 18
0
        private void CreatePortMapListen(UdpClient udpClient, Mapping mapping)
        {
            IPEndPoint endPoint = new IPEndPoint(LocalAddress, PmpConstants.ServerPort);

            while (true)
            {
                byte[] data = udpClient.Receive(ref endPoint);

                if (data.Length < 16)
                {
                    continue;
                }

                if (data[0] != PmpConstants.Version)
                {
                    continue;
                }

                byte opCode = (byte)(data[1] & 127);

                NetworkProtocolType protocol = NetworkProtocolType.Tcp;
                if (opCode == PmpConstants.OperationCodeUdp)
                {
                    protocol = NetworkProtocolType.Udp;
                }

                short resultCode = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 2));
                int   epoch      = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 4));

                short privatePort = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 8));
                short publicPort  = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(data, 10));

                uint lifetime = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(data, 12));

                if (privatePort < 0 || publicPort < 0 || resultCode != PmpConstants.ResultCodeSuccess)
                {
                    string[] errors = new[]
                    {
                        "Success",
                        "Unsupported Version",
                        "Not Authorized/Refused (e.g. box supports mapping, but user has turned feature off)"
                        ,
                        "Network Failure (e.g. NAT box itself has not obtained a DHCP lease)",
                        "Out of resources (NAT box cannot create any more mappings at this time)",
                        "Unsupported opcode"
                    };
                    throw new MappingException(resultCode, errors[resultCode]);
                }

                if (lifetime == 0)
                {
                    return;                                //mapping was deleted
                }
                //mapping was created
                //TODO: verify that the private port+protocol are a match
                mapping.PublicPort          = publicPort;
                mapping.NetworkProtocolType = protocol;
                mapping.Expiration          = DateTime.Now.AddSeconds(lifetime);
                return;
            }
        }
Exemplo n.º 19
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Mapping"/> class.
 /// </summary>
 /// <param name="networkProtocolType">The protocol.</param>
 /// <param name="privatePort">The private port.</param>
 /// <param name="publicPort">The public port.</param>
 /// <param name="lifetime">The lifetime.</param>
 /// <param name="description">The description.</param>
 public Mapping(NetworkProtocolType networkProtocolType, int privatePort, int publicPort, int lifetime, string description)
     : this(networkProtocolType, IPAddress.None, privatePort, publicPort, lifetime, description)
 {
 }
Exemplo n.º 20
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Mapping"/> class.
 /// </summary>
 /// <param name="networkProtocolType">The protocol.</param>
 /// <param name="privatePort">The private port.</param>
 /// <param name="publicPort">The public port.</param>
 /// <remarks>
 /// This constructor initializes a Permanent mapping. The description by deafult is "Open.NAT"
 /// </remarks>
 public Mapping(NetworkProtocolType networkProtocolType, int privatePort, int publicPort)
     : this(networkProtocolType, IPAddress.None, privatePort, publicPort, 0, "Open.NAT")
 {
 }
Exemplo n.º 21
0
        protected virtual bool TryCreateGame(JoinGameRequest operation, NetworkProtocolType expectedProtocol, bool createIfNotExists,
                                             out bool gameCreated, out GameState gameState, out OperationResponse errorResponse, Dictionary <string, object> authCookie)
        {
            var gameId     = operation.GameId;
            var properties = operation.GameProperties;

            gameState   = null;
            gameCreated = false;

            Func <GameServerContext, bool> filter = ctx =>
            {
                if (ctx.SupportedProtocols == null)
                {
                    return(true);
                }
                return(ctx.SupportedProtocols.Contains((byte)expectedProtocol));
            };

            // try to get a game server instance from the load balancer
            GameServerContext gameServerContext;

            if (!this.Application.LoadBalancer.TryGetServer(out gameServerContext, filter))
            {
                errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                {
                    ReturnCode   = (short)ErrorCode.ServerFull,
                    DebugMessage = LBErrorMessages.FailedToGetServerInstance,
                };

                return(false);
            }

            ErrorCode errorCode;
            string    errorMsg;

            // try to create or get game state
            if (createIfNotExists)
            {
                gameCreated = this.Application.GetOrCreateGame(gameId, this, (byte)this.MaxPlayersDefault, gameServerContext, out gameState, out errorCode, out errorMsg);
                if (errorCode != ErrorCode.Ok)
                {
                    errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                    {
                        ReturnCode   = (short)errorCode,
                        DebugMessage = errorMsg,
                    };

                    return(false);
                }
            }
            else
            {
                if (!this.Application.TryCreateGame(gameId, this, (byte)this.MaxPlayersDefault, gameServerContext, out gameState, out errorCode, out errorMsg))
                {
                    errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                    {
                        ReturnCode   = (short)errorCode,
                        DebugMessage = errorMsg,
                    };

                    return(false);
                }

                gameCreated = true;
            }

            if (gameCreated)
            {
                gameState.CreateRequest = operation;
            }

            if (properties != null)
            {
                bool   changed;
                string debugMessage;

                if (!gameState.TrySetProperties(properties, out changed, out debugMessage))
                {
                    if (gameCreated)
                    {
                        this.Application.RemoveGameByName(gameId);
                    }

                    errorResponse = new OperationResponse(operation.OperationRequest.OperationCode)
                    {
                        ReturnCode   = (short)ErrorCode.OperationInvalid,
                        DebugMessage = debugMessage
                    };
                    return(false);
                }
            }

            try
            {
                this.GameList.AddGameState(gameState, authCookie);
            }
            catch (Exception)
            {
                log.ErrorFormat("New game state:{0}", gameState.ToString());
                log.ErrorFormat("Request Params for new state:{0}", Newtonsoft.Json.JsonConvert.SerializeObject(operation, serializeSettings));
                log.ErrorFormat("CreateIfNotExists: {0}, GameCreated: {1}, Game Properties:{2}",
                                createIfNotExists, gameCreated, Newtonsoft.Json.JsonConvert.SerializeObject(properties, serializeSettings));

                GameState gameInApp;
                if (this.Application.TryGetGame(gameId, out gameInApp))
                {
                    log.ErrorFormat("Game state in app:{0}", gameInApp.ToString());
                    log.ErrorFormat("Request Params for Game in App:{0}",
                                    Newtonsoft.Json.JsonConvert.SerializeObject(gameInApp.CreateRequest, serializeSettings));
                }

                this.Application.RemoveGameByName(gameState.Id);
                gameCreated = false;

                GameState gameStateInList;
                if (this.GameList.TryGetGame(gameState.Id, out gameStateInList))
                {
                    log.ErrorFormat("Game state in list:{0}", gameStateInList.ToString());
                    log.ErrorFormat("Request Params for Game in list:{0}",
                                    Newtonsoft.Json.JsonConvert.SerializeObject(gameStateInList.CreateRequest, serializeSettings));
                }
                else
                {
                    log.ErrorFormat("Game state {0} not found in list", gameState.Id);
                }
                throw;
            }

            this.SchedulePublishGameChanges();

            errorResponse = null;
            return(true);
        }
		private static NetworkProtocol CreateNetworkProtocol(NetworkProtocolType protocolType, string ports, bool enabled) {
			return new NetworkProtocol() {
				name = protocolType,
				port = ports == null ? null : ports.Split(new[] { ';', ' ', ',' }, StringSplitOptions.RemoveEmptyEntries).Select(p => Int32.Parse(p)).ToArray(),
				enabled = enabled
			};
		}
#pragma warning disable 4014
        public static void ForwardPort(NetworkProtocolType networkProtocolType = NetworkProtocolType.Udp, int milisecondsDelay = 10000)
        {
            ForwardPortInternalAsync(LiteNetLib4MirrorTransport.Singleton.port, milisecondsDelay, networkProtocolType);
        }
Exemplo n.º 24
0
 /// <summary>
 /// Gets the specified mapping asynchronous.
 /// </summary>
 /// <param name="networkProtocolType">The protocol.</param>
 /// <param name="port">The port.</param>
 /// <returns>
 /// The matching mapping
 /// </returns>
 public abstract Task <Mapping> GetSpecificMappingAsync(NetworkProtocolType networkProtocolType, int port);
#pragma warning restore 4014

        private static async Task ForwardPortInternalAsync(ushort port, int milisecondsDelay, NetworkProtocolType networkProtocolType = NetworkProtocolType.Udp)
        {
            try
            {
                if (LastForwardedPort == port || UpnpFailed)
                {
                    return;
                }
                if (LastForwardedPort != 0)
                {
                    NatDiscoverer.ReleaseAll();
                }
                NatDiscoverer discoverer = new NatDiscoverer();
                NatDevice     device;
                using (CancellationTokenSource cts = new CancellationTokenSource(milisecondsDelay))
                {
                    device = await discoverer.DiscoverDeviceAsync(PortMapper.Upnp | PortMapper.Pmp, cts).ConfigureAwait(false);
                }

                await device.CreatePortMapAsync(new Mapping(networkProtocolType, port, port, "LiteNetLib4Mirror UPnP")).ConfigureAwait(false);

                LastForwardedPort = port;
                Debug.Log("Port forwarded successfully!");
            }
            catch
            {
                Debug.LogWarning("UPnP failed!");
                UpnpFailed = true;
            }
        }
Exemplo n.º 26
0
 public GetSpecificPortMappingEntryRequestMessage(NetworkProtocolType networkProtocolType, int externalPort)
 {
     _networkProtocolType = networkProtocolType;
     _externalPort        = externalPort;
 }
        private void OnGetApplicationAccount(ApplicationAccount account, AuthenticateRequest request, SendParameters sendParameters, NetworkProtocolType endpointProtocol)
        {
            if (!this.Connected)
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("OnGetApplicationAccount: Client disconnected. Ignore response.");
                }
                return;
            }

            if (!ConnectionRequirementsChecker.Check(this, account.RequireSecureConnection, account.ApplicationId, this.authOnceUsed))
            {
                log.Warn(secureConnectionLogGuard,
                         $"Client used non secure connection type when it is required. appId:{account.ApplicationId}, Connection: {this.NetworkProtocol}. AuthOnce {this.authOnceUsed}");

                return;
            }


            if (log.IsDebugEnabled)
            {
                log.DebugFormat("OnGetApplicationAccount app:{0}, result:{1}, msg:{2}", account.ApplicationId,
                                account.AccountServiceResult, account.DebugMessage);
            }

            var operationRequest = request.OperationRequest;

            if (!account.IsAuthenticated)
            {
                if (log.IsInfoEnabled)
                {
                    log.InfoFormat("Authentication of client failed: Msg={0}, AppId={1}", account.DebugMessage, request.ApplicationId);
                }

                this.SendOperationResponse(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode   = (short)ErrorCode.InvalidAuthentication,
                    DebugMessage =
                        string.IsNullOrEmpty(account.DebugMessage) ? ErrorMessages.InvalidAppId : account.DebugMessage
                }, sendParameters);

                this.ScheduleDisconnect(this.GetDisconnectTime());
                return;
            }

            if (log.IsDebugEnabled)
            {
                log.DebugFormat(
                    "HandleAuthenticateRequest for App ID {0}, Private Cloud {1}, Service Type {2}, Region {3}",
                    request.ApplicationId,
                    account.PrivateCloud,
                    account.ServiceType,
                    request.Region);
            }

            // store for debugging purposes.
            this.authenticatedApplicationId = request.ApplicationId;

            // try to get the master server instance for the specified application id
            CloudPhotonEndpointInfo masterServer;
            string message;

            if (!((PhotonCloudApp)this.application).CloudCache.TryGetPhotonEndpoint(request, account, out masterServer, out message))
            {
                if (string.Equals(request.Region, "none", StringComparison.CurrentCultureIgnoreCase))
                {
                    if (log.IsDebugEnabled)
                    {
                        log.DebugFormat("MasterServer not found for region '{0}' on cloud '{1}' / service type '{2}': '{3}'. AppId: {4}/{5}",
                                        request.Region, account.PrivateCloud, account.ServiceType, message,
                                        request.ApplicationId, request.ApplicationVersion);
                    }
                }
                else
                {
                    if (log.IsWarnEnabled)
                    {
                        log.WarnFormat(masterNotFoundGuard, "MasterServer not found for region '{0}' on cloud '{1}' / service type '{2}': '{3}'. AppId: {4}/{5}",
                                       request.Region, account.PrivateCloud, account.ServiceType, message,
                                       request.ApplicationId, request.ApplicationVersion);
                    }
                }
                this.SendOperationResponse(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode   = (short)ErrorCode.InvalidRegion,
                    DebugMessage = string.Format("Cloud {0} / Region {1} is not available.", account.PrivateCloud, request.Region)
                }, sendParameters);

                this.ScheduleDisconnect(this.GetDisconnectTime());
                return;
            }

            var masterEndPoint = masterServer.GetEndPoint(endpointProtocol, this.LocalPort,
                                                          isIPv6: this.LocalIPAddressIsIPv6, useHostnames: this.IsIPv6ToIPv4Bridged);

            if (masterEndPoint == null)
            {
                if (log.IsWarnEnabled)
                {
                    log.WarnFormat(masterNotFoundForProtocolGuard,
                                   "Master server endpoint for protocol {0} not found on master server {1}. appId:{2}",
                                   this.NetworkProtocol, masterServer, account.ApplicationId);
                }

                this.SendOperationResponse(new OperationResponse(operationRequest.OperationCode)
                {
                    ReturnCode   = (short)AuthErrorCode.ProtocolNotSupported,
                    DebugMessage = ErrorMessages.ProtocolNotSupported
                }, sendParameters);

                this.ScheduleDisconnect(this.GetDisconnectTime());
                return;
            }

            // check for custom authentication
            if (account.IsClientAuthenticationEnabled)
            {
                var customAuthHandler = this.GetCustomAuthHandler(account);
                customAuthHandler.AuthenticateClient(this, request, account, sendParameters, account);

                return; // custom authentication is handled async
            }

            var response = this.HandleDefaultAuthenticateRequest(request, account, masterEndPoint, masterServer);

            this.SendOperationResponse(response, sendParameters);
            this.ScheduleDisconnect(this.MaxDisconnectTime);
        }
 private static Tuple<bool, string> GetProtocolPorts(NetworkProtocol[] protocols, NetworkProtocolType protocolType)
 {
     if (protocols == null) {
         return Tuple.Create(false, "");
     }
     var enabled = false;
     var ports = new List<int>();
     foreach (var protocol in protocols.Where(p => p != null && p.name == protocolType)) {
         if (protocol.enabled && !enabled) {
             enabled = true;
             ports.Clear();
         }
         if (protocol.port != null) {
             ports.AddRange(protocol.port);
         }
     }
     return Tuple.Create(enabled, String.Join("; ", ports.Select(p => p.ToString())));
 }
		private static Tuple<bool, string> GetProtocolPorts(NetworkProtocol[] protocols, NetworkProtocolType protocolType) {
			if (protocols == null) {
				return Tuple.Create(false, "");
			}
			var enabled = false;
			var ports = new List<int>();
			foreach (var protocol in protocols.Where(p => p != null && p.name == protocolType)) {
				if (protocol.enabled && !enabled) {
					enabled = true;
					ports.Clear();
				}
				if (protocol.port != null) {
					ports.AddRange(protocol.port);
				}
			}
			return Tuple.Create(enabled, String.Join("; ", ports.Select(p => p.ToString())));
		}
Exemplo n.º 30
0
 internal Mapping(NetworkProtocolType networkProtocolType, IPAddress privateIP, int privatePort, int publicPort)
     : this(networkProtocolType, privateIP, privatePort, publicPort, 0, "LiteNetLib4Mirror.Open.Nat")
 {
 }