private async Task RespondToV2Message(string messageText, IpEndPointInfo endpoint, Encoding encoding, CancellationToken cancellationToken) { var parts = messageText.Split('|'); var localUrl = await _appHost.GetLocalApiUrl(cancellationToken).ConfigureAwait(false); if (!string.IsNullOrEmpty(localUrl)) { var response = new ServerDiscoveryInfo { Address = localUrl, Id = _appHost.SystemId, Name = _appHost.FriendlyName }; await SendAsync(encoding.GetBytes(_json.SerializeToString(response)), endpoint, cancellationToken).ConfigureAwait(false); if (parts.Length > 1) { _appHost.EnableLoopback(parts[1]); } } else { _logger.LogWarning("Unable to respond to udp request because the local ip address could not be determined."); } }
private void CreateSocket() { try { sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode); } catch (SocketCreateException ex) { if (_enableDualMode && endpoint.IpAddress.Equals(IpAddressInfo.IPv6Any) && (string.Equals(ex.ErrorCode, "AddressFamilyNotSupported", StringComparison.OrdinalIgnoreCase) || // mono on bsd is throwing this string.Equals(ex.ErrorCode, "ProtocolNotSupported", StringComparison.OrdinalIgnoreCase))) { endpoint = new IpEndPointInfo(IpAddressInfo.Any, endpoint.Port); _enableDualMode = false; sock = _socketFactory.CreateSocket(endpoint.IpAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp, _enableDualMode); } else { throw; } } sock.Bind(endpoint); // This is the number TcpListener uses. sock.Listen(2147483647); sock.StartAccept(ProcessAccept, () => _closed); _closed = false; }
private List <ISocket> GetSendSockets(IpAddressInfo fromLocalIpAddress, IpEndPointInfo destination) { EnsureSendSocketCreated(); lock (_SendSocketSynchroniser) { var sockets = _sendSockets.Where(i => i.LocalIPAddress.AddressFamily == fromLocalIpAddress.AddressFamily); // Send from the Any socket and the socket with the matching address if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetwork) { sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); // If sending to the loopback address, filter the socket list as well if (destination.IpAddress.Equals(IpAddressInfo.Loopback)) { sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.Any) || i.LocalIPAddress.Equals(IpAddressInfo.Loopback)); } } else if (fromLocalIpAddress.AddressFamily == IpAddressFamily.InterNetworkV6) { sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || fromLocalIpAddress.Equals(i.LocalIPAddress)); // If sending to the loopback address, filter the socket list as well if (destination.IpAddress.Equals(IpAddressInfo.IPv6Loopback)) { sockets = sockets.Where(i => i.LocalIPAddress.Equals(IpAddressInfo.IPv6Any) || i.LocalIPAddress.Equals(IpAddressInfo.IPv6Loopback)); } } return(sockets.ToList()); } }
/// <summary> /// Sends a message to a particular address (uni or multicast) and port. /// </summary> public async Task SendMessage(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) { if (messageData == null) { throw new ArgumentNullException("messageData"); } ThrowIfDisposed(); var sockets = GetSendSockets(fromLocalIpAddress, destination); if (sockets.Count == 0) { return; } // SSDP spec recommends sending messages multiple times (not more than 3) to account for possible packet loss over UDP. for (var i = 0; i < SsdpConstants.UdpResendCount; i++) { var tasks = sockets.Select(s => SendFromSocket(s, messageData, destination, cancellationToken)).ToArray(); await Task.WhenAll(tasks).ConfigureAwait(false); await Task.Delay(100, cancellationToken).ConfigureAwait(false); } }
public Task SendToAsync(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken) { var taskCompletion = new TaskCompletionSource <int>(); Action <IAsyncResult> callback = callbackResult => { try { taskCompletion.TrySetResult(EndSendTo(callbackResult)); } catch (Exception ex) { taskCompletion.TrySetException(ex); } }; var result = BeginSendTo(buffer, offset, size, endPoint, new AsyncCallback(callback), null); if (result.CompletedSynchronously) { callback(result); } cancellationToken.Register(() => taskCompletion.TrySetCanceled()); return(taskCompletion.Task); }
public async Task SendAsync(byte[] bytes, IpEndPointInfo remoteEndPoint, CancellationToken cancellationToken) { if (_isDisposed) { throw new ObjectDisposedException(GetType().Name); } if (bytes == null) { throw new ArgumentNullException("bytes"); } if (remoteEndPoint == null) { throw new ArgumentNullException("remoteEndPoint"); } try { await _udpClient.SendToAsync(bytes, 0, bytes.Length, remoteEndPoint, cancellationToken).ConfigureAwait(false); _logger.Info("Udp message sent to {0}", remoteEndPoint); } catch (OperationCanceledException) { } catch (Exception ex) { _logger.ErrorException("Error sending message to {0}", ex, remoteEndPoint); } }
public IAsyncResult BeginSendTo(byte[] buffer, int offset, int size, IpEndPointInfo endPoint, AsyncCallback callback, object state) { ThrowIfDisposed(); var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint); return(_Socket.BeginSendTo(buffer, offset, size, SocketFlags.None, ipEndPoint, callback, state)); }
public static IPEndPoint ToIPEndPoint(IpEndPointInfo endpoint) { if (endpoint == null) { return(null); } return(new IPEndPoint(ToIPAddress(endpoint.IpAddress), endpoint.Port)); }
private void OnResponseReceived(HttpResponseMessage data, IpEndPointInfo endPoint) { var handlers = this.ResponseReceived; if (handlers != null) { handlers(this, new ResponseReceivedEventArgs(data, endPoint)); } }
public UdpSocket(Socket socket, IpEndPointInfo endPoint) { if (socket == null) { throw new ArgumentNullException("socket"); } _Socket = socket; _Socket.Connect(NetworkManager.ToIPEndPoint(endPoint)); }
public Task SendAsync(byte[] buffer, int size, IpEndPointInfo endPoint) { ThrowIfDisposed(); if (buffer == null) { throw new ArgumentNullException("messageData"); } if (endPoint == null) { throw new ArgumentNullException("endPoint"); } var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint); #if NETSTANDARD1_6 if (size != buffer.Length) { byte[] copy = new byte[size]; Buffer.BlockCopy(buffer, 0, copy, 0, size); buffer = copy; } _Socket.SendTo(buffer, ipEndPoint); return(Task.FromResult(true)); #else var taskSource = new TaskCompletionSource <bool>(); try { _Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, ipEndPoint, result => { try { _Socket.EndSend(result); taskSource.TrySetResult(true); } catch (Exception ex) { taskSource.TrySetException(ex); } }, null); } catch (Exception ex) { taskSource.TrySetException(ex); } //_Socket.SendTo(messageData, new System.Net.IPEndPoint(IPAddress.Parse(RemoteEndPoint.IPAddress), RemoteEndPoint.Port)); return(taskSource.Task); #endif }
public UdpSocket(Socket socket, IpEndPointInfo endPoint) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } _Socket = socket; _Socket.Connect(NetworkManager.ToIPEndPoint(endPoint)); InitReceiveSocketAsyncEventArgs(); }
private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress, CancellationToken cancellationToken) { bool isRootDevice = (device as SsdpRootDevice) != null; if (isRootDevice) { SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress, cancellationToken); } SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress, cancellationToken); SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint, receivedOnlocalIpAddress, cancellationToken); }
private static async Task <bool> CheckTunerAvailability(ISocket socket, IpAddressInfo remoteIp, int tuner, CancellationToken cancellationToken) { var ipEndPoint = new IpEndPointInfo(remoteIp, HdHomeRunPort); var lockkeyMsg = CreateGetMessage(tuner, "lockkey"); await socket.SendToAsync(lockkeyMsg, 0, lockkeyMsg.Length, ipEndPoint, cancellationToken); var receiveBuffer = new byte[8192]; var response = await socket.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, cancellationToken).ConfigureAwait(false); ParseReturnMessage(response.Buffer, response.ReceivedBytes, out string returnVal); return(string.Equals(returnVal, "none", StringComparison.OrdinalIgnoreCase)); }
private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken) { var sockets = _sendSockets; if (sockets != null) { sockets = sockets.ToList(); var tasks = sockets.Select(s => SendFromSocket(s, messageData, destination, cancellationToken)); return(Task.WhenAll(tasks)); } return(Task.CompletedTask); }
private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken) { var sockets = _sendSockets; if (sockets != null) { sockets = sockets.ToList(); foreach (var socket in sockets) { await SendFromSocket(socket, messageData, destination, cancellationToken).ConfigureAwait(false); } } }
private async Task SendFromSocket(IUdpSocket socket, byte[] messageData, IpEndPointInfo destination) { try { await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false); } catch (ObjectDisposedException) { } catch (Exception ex) { _logger.ErrorException("Error sending socket message from {0} to {1}", ex, socket.LocalIPAddress.ToString(), destination.ToString()); } }
private Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination, IpAddressInfo fromLocalIpAddress, CancellationToken cancellationToken) { var sockets = _sendSockets; if (sockets != null) { sockets = sockets.ToList(); var tasks = sockets.Where(s => (fromLocalIpAddress == null || fromLocalIpAddress.Equals(s.LocalIPAddress))) .Select(s => SendFromSocket(s, messageData, destination, cancellationToken)); return(Task.WhenAll(tasks)); } return(Task.CompletedTask); }
public async Task SendWithLockAsync(byte[] buffer, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken) { ThrowIfDisposed(); //await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false); try { await SendAsync(buffer, size, endPoint, cancellationToken).ConfigureAwait(false); } finally { //_sendLock.Release(); } }
private async Task SendMessageIfSocketNotDisposed(byte[] messageData, IpEndPointInfo destination) { var sockets = _sendSockets; if (sockets != null) { sockets = sockets.ToList(); foreach (var socket in sockets) { await socket.SendAsync(messageData, messageData.Length, destination).ConfigureAwait(false); } } ThrowIfDisposed(); }
private void SendDeviceSearchResponses(SsdpDevice device, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress) { bool isRootDevice = (device as SsdpRootDevice) != null; if (isRootDevice) { SendSearchResponse(SsdpConstants.UpnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.UpnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress); if (this.SupportPnpRootDevice) { SendSearchResponse(SsdpConstants.PnpDeviceTypeRootDevice, device, GetUsn(device.Udn, SsdpConstants.PnpDeviceTypeRootDevice), endPoint, receivedOnlocalIpAddress); } } SendSearchResponse(device.Udn, device, device.Udn, endPoint, receivedOnlocalIpAddress); SendSearchResponse(device.FullDeviceType, device, GetUsn(device.Udn, device.FullDeviceType), endPoint, receivedOnlocalIpAddress); }
private void OnRequestReceived(HttpRequestMessage data, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnLocalIpAddress) { //SSDP specification says only * is currently used but other uri's might //be implemented in the future and should be ignored unless understood. //Section 4.2 - http://tools.ietf.org/html/draft-cai-ssdp-v1-03#page-11 if (data.RequestUri.ToString() != "*") { return; } var handlers = this.RequestReceived; if (handlers != null) { handlers(this, new RequestReceivedEventArgs(data, remoteEndPoint, receivedOnLocalIpAddress)); } }
private async Task SendFromSocket(ISocket socket, byte[] messageData, IpEndPointInfo destination, CancellationToken cancellationToken) { try { await socket.SendToAsync(messageData, 0, messageData.Length, destination, cancellationToken).ConfigureAwait(false); } catch (ObjectDisposedException) { } catch (OperationCanceledException) { } catch (Exception ex) { _logger.LogError(ex, "Error sending socket message from {0} to {1}", socket.LocalIPAddress.ToString(), destination.ToString()); } }
public static void RemoveEndPoint(EndPointListener epl, IpEndPointInfo ep) { lock (ip_to_endpoints) { // Dictionary<int, EndPointListener> p Dictionary <int, EndPointListener> p; if (ip_to_endpoints.TryGetValue(ep.IpAddress.Address, out p)) { p.Remove(ep.Port); if (p.Count == 0) { ip_to_endpoints.Remove(ep.IpAddress.Address); } } epl.Close(); } }
private async Task ReleaseLockkey(ISocket tcpClient, uint lockKeyValue) { _logger.Info("HdHomerunManager.ReleaseLockkey {0}", lockKeyValue); var ipEndPoint = new IpEndPointInfo(_remoteIp, HdHomeRunPort); var releaseTarget = CreateSetMessage(_activeTuner, "target", "none", lockKeyValue); await tcpClient.SendToAsync(releaseTarget, 0, releaseTarget.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false); var receiveBuffer = new byte[8192]; await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, CancellationToken.None).ConfigureAwait(false); var releaseKeyMsg = CreateSetMessage(_activeTuner, "lockkey", "none", lockKeyValue); _lockkey = null; await tcpClient.SendToAsync(releaseKeyMsg, 0, releaseKeyMsg.Length, ipEndPoint, CancellationToken.None).ConfigureAwait(false); await tcpClient.ReceiveAsync(receiveBuffer, 0, receiveBuffer.Length, CancellationToken.None).ConfigureAwait(false); }
private void ProcessMessage(string data, IpEndPointInfo endPoint, IpAddressInfo receivedOnLocalIpAddress) { //Responses start with the HTTP version, prefixed with HTTP/ while //requests start with a method which can vary and might be one we haven't //seen/don't know. We'll check if this message is a request or a response //by checking for the HTTP/ prefix on the start of the message. if (data.StartsWith("HTTP/", StringComparison.OrdinalIgnoreCase)) { HttpResponseMessage responseMessage = null; try { responseMessage = _ResponseParser.Parse(data); } catch (ArgumentException) { // Ignore invalid packets. } if (responseMessage != null) { OnResponseReceived(responseMessage, endPoint, receivedOnLocalIpAddress); } } else { HttpRequestMessage requestMessage = null; try { requestMessage = _RequestParser.Parse(data); } catch (ArgumentException) { // Ignore invalid packets. } if (requestMessage != null) { OnRequestReceived(requestMessage, endPoint, receivedOnLocalIpAddress); } } }
public EndPointListener(HttpListener listener, IpAddressInfo addr, int port, bool secure, ICertificate cert, ILogger logger, ICryptoProvider cryptoProvider, IStreamFactory streamFactory, ISocketFactory socketFactory, IMemoryStreamFactory memoryStreamFactory, ITextEncoding textEncoding) { this.listener = listener; _logger = logger; _cryptoProvider = cryptoProvider; _streamFactory = streamFactory; _socketFactory = socketFactory; _memoryStreamFactory = memoryStreamFactory; _textEncoding = textEncoding; this.secure = secure; this.cert = cert; _enableDualMode = addr.Equals(IpAddressInfo.IPv6Any); endpoint = new IpEndPointInfo(addr, port); prefixes = new Dictionary <ListenerPrefix, HttpListener>(); unregistered = new Dictionary <HttpConnection, HttpConnection>(); CreateSocket(); }
private async void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, IpEndPointInfo endPoint, IpAddressInfo receivedOnlocalIpAddress) { var rootDevice = device.ToRootDevice(); //var additionalheaders = FormatCustomHeadersForResponse(device); const string header = "HTTP/1.1 200 OK"; var values = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); values["EXT"] = ""; values["DATE"] = DateTime.UtcNow.ToString("r"); values["CACHE-CONTROL"] = "max-age = 600"; values["ST"] = searchTarget; values["SERVER"] = string.Format("{0}/{1} UPnP/1.0 RSSDP/{2}", _OSName, _OSVersion, ServerVersion); values["USN"] = uniqueServiceName; values["LOCATION"] = rootDevice.Location.ToString(); var message = SsdpHelper.BuildMessage(header, values); try { await _CommsServer.SendMessage(System.Text.Encoding.UTF8.GetBytes(message), endPoint, receivedOnlocalIpAddress).ConfigureAwait(false); } catch (Exception ex) { } //WriteTrace(String.Format("Sent search response to " + endPoint.ToString()), device); }
private void ProcessSearchRequest(string mx, string searchTarget, IpEndPointInfo remoteEndPoint, IpAddressInfo receivedOnlocalIpAddress) { if (String.IsNullOrEmpty(searchTarget)) { WriteTrace(String.Format("Invalid search request received From {0}, Target is null/empty.", remoteEndPoint.ToString())); return; } //WriteTrace(String.Format("Search Request Received From {0}, Target = {1}", remoteEndPoint.ToString(), searchTarget)); if (IsDuplicateSearchRequest(searchTarget, remoteEndPoint)) { //WriteTrace("Search Request is Duplicate, ignoring."); return; } //Wait on random interval up to MX, as per SSDP spec. //Also, as per UPnP 1.1/SSDP spec ignore missing/bank MX header. If over 120, assume random value between 0 and 120. //Using 16 as minimum as that's often the minimum system clock frequency anyway. int maxWaitInterval = 0; if (String.IsNullOrEmpty(mx)) { //Windows Explorer is poorly behaved and doesn't supply an MX header value. //if (this.SupportPnpRootDevice) mx = "1"; //else //return; } if (!Int32.TryParse(mx, out maxWaitInterval) || maxWaitInterval <= 0) { return; } if (maxWaitInterval > 120) { maxWaitInterval = _Random.Next(0, 120); } //Do not block synchronously as that may tie up a threadpool thread for several seconds. Task.Delay(_Random.Next(16, (maxWaitInterval * 1000))).ContinueWith((parentTask) => { //Copying devices to local array here to avoid threading issues/enumerator exceptions. IEnumerable <SsdpDevice> devices = null; lock (_Devices) { if (String.Compare(SsdpConstants.SsdpDiscoverAllSTHeader, searchTarget, StringComparison.OrdinalIgnoreCase) == 0) { devices = GetAllDevicesAsFlatEnumerable().ToArray(); } else if (String.Compare(SsdpConstants.UpnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 || (this.SupportPnpRootDevice && String.Compare(SsdpConstants.PnpDeviceTypeRootDevice, searchTarget, StringComparison.OrdinalIgnoreCase) == 0)) { devices = _Devices.ToArray(); } else if (searchTarget.Trim().StartsWith("uuid:", StringComparison.OrdinalIgnoreCase)) { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.Uuid, searchTarget.Substring(5), StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); } else if (searchTarget.StartsWith("urn:", StringComparison.OrdinalIgnoreCase)) { devices = (from device in GetAllDevicesAsFlatEnumerable() where String.Compare(device.FullDeviceType, searchTarget, StringComparison.OrdinalIgnoreCase) == 0 select device).ToArray(); } } if (devices != null) { var deviceList = devices.ToList(); //WriteTrace(String.Format("Sending {0} search responses", deviceList.Count)); foreach (var device in deviceList) { SendDeviceSearchResponses(device, remoteEndPoint, receivedOnlocalIpAddress); } } else { //WriteTrace(String.Format("Sending 0 search responses.")); } }); }
/// <summary> /// Full constructor. /// </summary> public ResponseReceivedEventArgs(HttpResponseMessage message, IpEndPointInfo receivedFrom) { _Message = message; _ReceivedFrom = receivedFrom; }