/// <summary> Handles connecting status. Tracks attempted connections and (re)sends connection data. </summary> private void Connect(IPEndPoint ep, NetStream approvalData) { if (!connectingEndpoints.Contains(ep)) { // We aren't currently trying to connect to this endpoint, add to lists: connectingEndpoints.Add(ep); connectingTimes.Add(NetTime.Milliseconds()); connectingData.Add(approvalData); connectingRetriesRemaining.Add(4); NetLog.Info("Connecting to: " + ep); } else { // We are already trying to connect, update attempt data: int index = connectingEndpoints.IndexOf(ep); connectingRetriesRemaining[index]--; if (connectingRetriesRemaining[index] <= 0) { // Retried max amount of times, notify failure: RemoveFromConnecting(ep, false); return; } connectingTimes[index] = NetTime.Milliseconds(); NetLog.Info("Retrying connection to: " + ep); } // Send the connection request data to the endpoint: SendStream(ep, approvalData); }
public IEnumerator SetServer(NetConnection server, NetZone zone) { zone.Assigned = true; if (server != Socket.Self) { var setServerRequest = Socket.Request.Send <string>("AssignZone", server, zone); yield return(setServerRequest.WaitUntilDone); if (!setServerRequest.IsSuccessful) { zone.Assigned = false; yield break; } zone.PublicEndpoint = setServerRequest.Result; } else { NetZoneServer zoneServ = GetComponent <NetZoneServer>(); zoneServ.AssignZoneSelf(zone); } zone.Server = server; zone.ServerEndpoint = zone.Server.Endpoint; if (string.IsNullOrEmpty(zone.PublicEndpoint)) { zone.PublicEndpoint = zone.Server.Endpoint.ToString(); } ZoneAssigned(zone); NetLog.Info("Server assigned to zone. Endpoint: " + server.Endpoint); zone.Available = true; }
private void ReceivePeerConnectionRequest(IPEndPoint endpoint, NetStream readStream) { if (!AcceptConnections || Connections.Count >= MaxConnections || !Events.PeerApproval(endpoint, readStream)) { NetLog.Info("Refused peer connection: " + endpoint); TrySend(new[] { (byte)ByteCmd.RefuseConnection }, 1, endpoint); } else { CreateConnection(endpoint, false, true); } }
private void PeerDisconnected(NetConnection connection) { NetLog.Info("ZoneManager: Peer Disconnected: " + connection.Endpoint); if (peers.Contains(connection)) { peers.Remove(connection); } if (Authority) { RemoveServer(connection); } }
internal void AssignZoneSelf(NetZone zone) { if (ViewManager.GenerateViewId == null) { ViewManager.GenerateViewId += AllocateViewId; } NetLog.Info("Assigned to zone."); self = zone; if (OnAssignment != null) { OnAssignment(); } }
private void PeerConnected(NetConnection connection) { if (!peerLookup.ContainsKey(connection.Endpoint)) { return; } NetZone peer = peerLookup[connection.Endpoint]; NetLog.Info("Connection is Zone Peer: " + peer); peer.Server = connection; connection.InternalScope = new NetScope(); connection.InternalScope.Position = peer.Position; connection.InternalScope.OutScopeDist = (int)(peer.HandoverMaxDistance * 1.25); connection.InternalScope.InScopeDist = peer.HandoverMaxDistance; }
/// <summary> Adds a new NetConnection to the connection list. </summary> internal NetConnection CreateConnection(IPEndPoint ep, bool isServer, bool isPeer) { bool wasServer = false; // Connection cannot be both server and peer: if (isPeer) { isServer = false; wasServer = true; } var connection = new NetConnection(isServer, isPeer, this, ep); Connections.Add(connection); endpointToConnection.Add(ep, connection); if (isPeer) { NetLog.Info("Peer connection created: " + ep); } else if (isServer) { NetLog.Info("Server connection created: " + ep); } else { NetLog.Info("Client connection created: " + ep); } if (ProtocolAuthority && !isServer && !wasServer) { SendConnectionRequirements(connection); Rpc.SendLocalAssignments(connection); } else if (connection.IsPeer && Rpc.IdCount == RpcInfoCache.Count) { Events.PeerConnected(connection); } else if (isServer && Rpc.IdCount == RpcInfoCache.Count) { Events.ConnectedToServer(connection); } else if (!isServer && !isPeer) { Events.ClientConnected(connection); } return(connection); }
private void ReceiveConnectionResponse(IPEndPoint endpoint, int bytesReceived, NetStream readStream) { bool isPeer = RemoveFromConnecting(endpoint, true); if (bytesReceived == 1 && readStream.Data[0] == (byte)ByteCmd.RefuseConnection) { NetLog.Info("Connection refused by: " + endpoint); return; } var connection = CreateConnection(endpoint, true, isPeer); if (bytesReceived > 1) { connection.ReceiveStream(readStream); } }
/// <summary> /// Starts the socket using the supplied endpoint. /// If the port is taken, the given port will be incremented to a free port. /// </summary> public void StartSocket(IPEndPoint endpoint) { Self = new NetConnection(false, false, this, endpoint); socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); try { const uint IOC_IN = 0x80000000; const uint IOC_VENDOR = 0x18000000; uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12; socket.IOControl((int)SIO_UDP_CONNRESET, new[] { Convert.ToByte(false) }, null); } catch { NetLog.Warning("Failed to set control code for ignoring ICMP port unreachable."); } socket.ReceiveBufferSize = 4194304; if (socket.ReceiveBufferSize != 4194304) { NetLog.Warning("ReceiveBufferSize restricted by OS."); } socket.SendBufferSize = 1048576; socket.Blocking = false; try { socket.Bind(endpoint); } catch (SocketException e) { if (e.ErrorCode == 10048) { var newEp = new IPEndPoint(endpoint.Address, endpoint.Port + 1); NetLog.Warning("Port in use. Incrementing and retrying..."); StartSocket(newEp); } else { NetLog.Error(e.Message); } return; } NetLog.Info(NetTime.StartDateTime() + " | Socket Started. Bound to: " + endpoint); NetTime.Milliseconds(); if (ProtocolAuthority) { Rpc.AssignLocalRpcs(); } Events.SocketStart(); }
/// <summary> Performs end-frame tasks such as flushing stream & checking timeouts. </summary> internal void EndOfFrame(uint currentTime) { if (ShouldDisconnect(currentTime)) { NetLog.Info("Disconnecting connection due to overflow or timeout: " + Endpoint); Disconnect(); return; } if (!Reliable.FlushStream() && Reliable.ShouldForceAck(currentTime)) { Reliable.ForceAck(); } if (!Unreliable.FlushStream() && ShouldSendHeartbeat(currentTime)) { Unreliable.SendHeartbeat(); } Reliable.CheckTimeouts(currentTime); }
internal void RemovePeerSelf(NetZone zone) { NetLog.Info("Removing zone"); if (peerLookup.ContainsKey(zone.ServerEndpoint)) { peerLookup.Remove(zone.ServerEndpoint); } else if (peerLookup.ContainsValue(zone)) { NetLog.Warning("RemovePeer: Zone endpoint mismatch."); } if (peers.Contains(zone)) { peers.Remove(zone); } else { NetLog.Info("RemovePeer: Zone not in peer list."); } }
/// <summary> Cleans up a connection attempt and returns true if it is a peer connection. </summary> internal bool RemoveFromConnecting(IPEndPoint ep, bool successful) { bool isPeer = false; if (!successful) { NetLog.Info("Failed to connect to: " + ep); Events.FailedToConnect(ep); } int index = connectingEndpoints.IndexOf(ep); connectingTimes.RemoveAt(index); connectingRetriesRemaining.RemoveAt(index); connectingEndpoints.Remove(ep); if (connectingData[index].Data[0] == (byte)ByteCmd.ConnectToPeer) { isPeer = true; } connectingData[index].Release(); connectingData.RemoveAt(index); return(isPeer); }