예제 #1
0
        internal void SendObject(object o)
        {
            serializer.SendNext(o);

            while (serializer.HasQueuedObjects)
            {
                UdpSendFailReason reason = CheckCanSend(false);

                if (reason != UdpSendFailReason.None)
                {
                    while (serializer.HasQueuedObjects)
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, serializer.NextObject(), reason);
                    }

                    break;
                }

                UdpStream stream     = socket.GetWriteStream(mtu << 3, UdpSocket.HeaderBitSize);
                var       initialPtr = stream.Ptr; // Erhune: added info
                object    obj        = serializer.NextObject();

                if (serializer.Pack(stream, ref obj))
                {
                    if (stream.Overflowing && (socket.Config.AllowPacketOverflow == false))
                    {
                        UdpLog.Error("Stream to {0} is overflowing (InitialPtr={1} Ptr={2} Len={3}), not sending {4}",
                                     endpoint.ToString(), initialPtr, stream.Ptr, stream.Length, obj); // Erhune: added info
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.StreamOverflow);
                        return;
                    }

                    UdpHeader header = MakeHeader(true);
                    header.Pack(stream, socket, shouldSendClock);

                    UdpHandle handle = MakeHandle(ref header);
                    handle.Object = obj;

                    if (SendStream(stream, handle, alwaysSendMtu))
                    {
                        // track stats
                        stats.PacketSent((uint)stream.Ptr >> 3);
                        socket.Statistics.PacketSent((uint)stream.Ptr >> 3);

                        // push object to user thread
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SENT, this, obj);
                    }
                    else
                    {
                        socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SocketError);
                    }
                }
                else
                {
                    socket.Raise(UdpEvent.PUBLIC_OBJECT_SEND_FAILED, this, obj, UdpSendFailReason.SerializerReturnedFalse);
                }
            }
        }
예제 #2
0
        public void ConnectServer(CClientNetworkCtrl clientNetworkCtrl)
        {
            //sever and client.
            localPort = clientNetworkCtrl.LocalPort;
            UdpEndPoint serverPoint = new UdpEndPoint(UdpIPv4Address.Any, (ushort)localPort);

            server.Start(serverPoint);
            IPAddress ipaddr = IPAddress.Parse(clientNetworkCtrl.ServerIP);

            hostUser.ProxyServer = new IPEndPoint(ipaddr, clientNetworkCtrl.ServerPort);

            UdpIPv4Address address = UdpIPv4Address.Parse(clientNetworkCtrl.ServerIP);
            UdpEndPoint    endp    = new UdpEndPoint(address, (ushort)clientNetworkCtrl.ServerPort);

            server.Connect(endp);

            Log.info("UdpClientNetWork", "UdpClientNetWork Start, UdpPort:" + localPort + " ServerIP:" + clientNetworkCtrl.ServerIP.ToString() + " ProxyServer address:" + endp.ToString());
            CtrlOwner = clientNetworkCtrl;
        }
예제 #3
0
        private void SendSearchResponse(string searchTarget, SsdpDevice device, string uniqueServiceName, UdpEndPoint endPoint)
        {
            var rootDevice = device.ToRootDevice();

            var additionalheaders = FormatCustomHeadersForResponse(device);

            var message = String.Format(DeviceSearchResponseMessageFormat,
                                        CacheControlHeaderFromTimeSpan(rootDevice),
                                        searchTarget,
                                        rootDevice.Udn,
                                        rootDevice.Location,
                                        _OSName,
                                        _OSVersion,
                                        "",
                                        DateTime.UtcNow.ToString("r"),
                                        additionalheaders
                                        );

            _CommsServer.SendMessage(System.Text.UTF8Encoding.UTF8.GetBytes(message), endPoint);

            LogDeviceEventVerbose(String.Format("Sent search response ({0}) to {1}", uniqueServiceName, endPoint.ToString()), device);
        }
예제 #4
0
        private void ProcessSearchRequest(string mx, string searchTarget, UdpEndPoint endPoint)
        {
            if (String.IsNullOrEmpty(searchTarget))
            {
                _Log.LogWarning(String.Format("Invalid search request received From {0}, Target is null/empty.", endPoint.ToString()));
                return;
            }

            _Log.LogInfo(String.Format("Search Request Received From {0}, Target = {1}", endPoint.ToString(), searchTarget));

            if (IsDuplicateSearchRequest(searchTarget, endPoint))
            {
                Log.LogWarning("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 (strict mode only). 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 (IsWindowsExplorerSupportEnabled)
                {
                    mx = "1";
                }
                else
                {
                    _Log.LogWarning("Search Request ignored due to missing MX header. Set StandardsMode to relaxed to respond to these requests.");
                    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;
                devices = GetDevicesMatchingSearchTarget(searchTarget, devices);

                if (devices != null)
                {
                    SendSearchResponses(searchTarget, endPoint, devices);
                }
                else
                {
                    _Log.LogWarning("Sending search responses for 0 devices (no matching targets).");
                }
            });
        }
예제 #5
0
        public override bool ConnectSync(IPEndPoint localAddress, IPEndPoint remoteAddress, int timeout)
        {
            long num = DateTime.Now.ToFileTime() / 10000L;
            bool result;

            if (IsConnected())
            {
                UdpIPv4Address udpIPv4Address = new UdpIPv4Address(NetUtil.GetLongAddress(remoteAddress.Address.GetAddressBytes()));
                UdpIPv4Address address        = this.udpRemote.Address;
                if (address.Equals(udpIPv4Address) && (int)udpRemote.Port == remoteAddress.Port)
                {
                    result = true;
                    return(result);
                }
                LoggerManager.Instance.Warn("ConnectSync found already connected new addr {0} old addr {1}", remoteAddress.ToString(), udpRemote.ToString());
            }

            if (!IsConnecting())
            {
                udpRemote = new UdpEndPoint(new UdpIPv4Address(NetUtil.GetLongAddress(remoteAddress.Address.GetAddressBytes())), (ushort)remoteAddress.Port);
                remote    = remoteAddress;
                socket.Connect(udpRemote);
            }

            object obj = statusLock;

            Monitor.Enter(obj);
            try
            {
                connectionStatus = ConnectionStatus.Connecting;
            }
            finally
            {
                Monitor.Exit(obj);
            }

            long num2 = DateTime.Now.ToFileTime() / 10000L;

            while (num2 - num < (long)(timeout * 1000))
            {
                UdpEvent ev;
                if (socket.Poll(out ev))
                {
                    UdpEventType eventType = ev.EventType;
                    switch (eventType)
                    {
                    case UdpEventType.ConnectFailed:
                    case UdpEventType.ConnectRefused:
                    case UdpEventType.Connected:
                        ProcessConnect(ev);
                        result = (ev.EventType == UdpEventType.Connected);
                        return(result);

                    case (UdpEventType)5:
                    case (UdpEventType)7:
                        break;

                    default:
                        if (eventType == UdpEventType.ServerForceQuit)
                        {
                            ProcessServerForceQuit(ev);
                            result = false;
                            return(result);
                        }
                        break;
                    }
                }
                Thread.Sleep(10);
                num2 = DateTime.Now.ToFileTime() / 10000L;
            }

            Monitor.Enter(obj = this.statusLock);
            try
            {
                connectionStatus = ConnectionStatus.Disconnected;
            }
            finally
            {
                Monitor.Exit(obj);
            }
            result = false;
            return(result);
        }