예제 #1
0
 private void RequestAnsweredSink(HTTPSession ss)
 {
     lock (TagQueue)
     {
         if (!ReceivedFirstResponse)
         {
             ReceivedFirstResponse = true;
             IEnumerator en = TagQueue.GetEnumerator();
             while (en.MoveNext())
             {
                 StateData sd = (StateData)en.Current;
                 try
                 {
                     if (ProxySetting == null)
                     {
                         ss.Send(sd.Request);
                     }
                     else
                     {
                         HTTPMessage pr = (HTTPMessage)sd.Request.Clone();
                         pr.DirectiveObj = "http://" + sd.Dest + pr.DirectiveObj;
                         pr.Version      = "1.0";
                         ss.Send(pr);
                     }
                 }
                 catch (Exception ex)
                 {
                     EventLogger.Log(ex);
                 }
             }
         }
     }
 }
예제 #2
0
 public StateData(HTTPMessage req, IPEndPoint d, object Tag, HeaderHandler HeaderCB)
 {
     Dest          = d;
     Request       = req;
     this.Tag      = Tag;
     this.HeaderCB = HeaderCB;
 }
예제 #3
0
        private void GetHostByNameSink(IAsyncResult result)
        {
            IPHostEntry e;

            try
            {
                e = Dns.EndGetHostEntry(result);
            }
            catch (Exception ex)
            {
                // Could not resolve?
                EventLogger.Log(ex);
                return;
            }

            object[] Args     = (object[])result.AsyncState;
            Uri      Resource = (Uri)Args[0];
            object   Tag      = Args[1];

            ContinueRequest(
                new IPEndPoint(e.AddressList[0], Resource.Port),
                HTTPMessage.UnEscapeString(Resource.PathAndQuery),
                Tag,
                null);
        }
예제 #4
0
 private void SniffPacketSink(HTTPMessage Packet)
 {
     if (OnSniffPacket != null)
     {
         OnSniffPacket(Packet);
     }
 }
예제 #5
0
        private void ReceiveSink(HTTPSession sender, HTTPMessage msg)
        {
            StateData sd  = (StateData)sender.StateObject;
            object    Tag = sd.Tag;

            if (msg.Version == "1.0" || msg.Version == "0.9")
            {
                sender.Close();
            }
            else
            {
                if (msg.GetTag("Connection").ToUpper() == "CLOSE")
                {
                    sender.Close();
                }
            }


            if (OnResponse != null)
            {
                OnResponse(this, msg, Tag);
            }
            // If I don't set this to null, this holds a strong reference, resulting in
            // possible memory leaks
            sender.StateObject = null;
            lock (TagQueue)
            {
                if (TagQueue.Count == 0)
                {
                    IdleTimeout = true;
                    KeepAliveTimer.Add(GetHashCode(), 10);
                }
            }
        }
예제 #6
0
 private void NonPipelinedSniffPacketSink(HTTPRequest sender, HTTPMessage Response, object Tag)
 {
     if (OnSniffPacket != null)
     {
         OnSniffPacket(this, Response, Tag);
     }
 }
예제 #7
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        private void OnReceiveSink(IAsyncResult result)
        {
            byte[]     buffer;
            IPEndPoint ep = null;

            object[]   args    = (object[])result.AsyncState;
            UdpClient  session = (UdpClient)args[0];
            IPEndPoint local   = (IPEndPoint)args[1];

            try
            {
                buffer = session.EndReceive(result, ref ep);
                try
                {
                    HTTPMessage Packet = HTTPMessage.ParseByteArray(buffer, 0, buffer.Length);
                    if (Packet != null)
                    {
                        Packet.LocalEndPoint  = local;
                        Packet.RemoteEndPoint = ep;
                        ProcessPacket(Packet, Packet.RemoteEndPoint, local);
                    }
                }
                catch (Exception ex)
                {
                    EventLogger.Log(ex);
                }
                session.BeginReceive(OnReceiveSink, args);
            }
            catch (Exception ex)
            {
                EventLogger.Log(ex);
                sessions.Remove(local.Address);
            }
        }
예제 #8
0
 private void NonPipelinedResponseSink(HTTPRequest sender, HTTPMessage Response, object Tag)
 {
     //			OpenSource.Utilities.EventLogger.Log(sender.s,System.Diagnostics.EventLogEntryType.Information,"TryingToDispose");
     _Source = sender.Source;
     NotPipelinedTable.Remove(sender);
     sender.Dispose();
     if (OnResponse != null)
     {
         OnResponse(this, Response, Tag);
     }
 }
예제 #9
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        /// <summary>
        /// Parses a URL
        /// </summary>
        /// <param name="ServiceURL">The URL to Parse</param>
        /// <param name="WebIP">The IPAddress</param>
        /// <param name="Port">The Port Number</param>
        /// <param name="ServiceName">The Object</param>
        static public void ParseURL(String ServiceURL, out String WebIP, out int Port, out String ServiceName)
        {
            Uri NewUri = new Uri(ServiceURL);

            WebIP = NewUri.Host;
            if (NewUri.HostNameType == UriHostNameType.Dns)
            {
                WebIP = Dns.GetHostEntry(WebIP).AddressList[0].ToString();
            }
            Port        = NewUri.Port;
            ServiceName = HTTPMessage.UnEscapeString(NewUri.PathAndQuery);
        }
예제 #10
0
        private void OnReceiveSink2(byte[] buffer, IPEndPoint remote, IPEndPoint local)
        {
            HTTPMessage msg;

            try
            {
                msg = HTTPMessage.ParseByteArray(buffer, 0, buffer.Length);
            }
            catch (Exception ex)
            {
                EventLogger.Log(ex);
                msg              = new HTTPMessage();
                msg.Directive    = "---";
                msg.DirectiveObj = "---";
                msg.BodyBuffer   = buffer;
            }
            msg.LocalEndPoint  = local;
            msg.RemoteEndPoint = remote;

            DText parser = new DText();

            String Location = msg.GetTag("Location");
            int    MaxAge   = 0;
            String ma       = msg.GetTag("Cache-Control").Trim();

            if (ma != "")
            {
                parser.ATTRMARK = ",";
                parser.MULTMARK = "=";
                parser[0]       = ma;
                for (int i = 1; i <= parser.DCOUNT(); ++i)
                {
                    if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                    {
                        MaxAge = int.Parse(parser[i, 2].Trim());
                        break;
                    }
                }
            }
            ma = msg.GetTag("USN");
            String USN = ma.Substring(ma.IndexOf(":") + 1);
            String ST  = msg.GetTag("ST");

            if (USN.IndexOf("::") != -1)
            {
                USN = USN.Substring(0, USN.IndexOf("::"));
            }
            EventLogger.Log(this, EventLogEntryType.SuccessAudit, msg.RemoteEndPoint.ToString());
            if (OnSearch != null)
            {
                OnSearch(msg.RemoteEndPoint, msg.LocalEndPoint, new Uri(Location), USN, ST, MaxAge);
            }
        }
예제 #11
0
        private void SniffPacketSink(HTTPSession sender, HTTPMessage MSG)
        {
            if (OnSniffPacket != null)
            {
                if (sender.StateObject == null)
                {
                    OnSniffPacket(this, MSG, null);
                    return;
                }
                StateData sd  = (StateData)sender.StateObject;
                object    Tag = sd.Tag;

                OnSniffPacket(this, MSG, Tag);
            }
        }
예제 #12
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        /// <summary>
        /// Multicasts a HTTPMessage
        /// </summary>
        /// <param name="packet">The Packet to Multicast</param>
        /// <param name="netinterface"></param>
        public void BroadcastData(HTTPMessage packet, IPAddress netinterface)
        {
            UdpClient usession = (UdpClient)usessions[netinterface];

            if (usession == null)
            {
                return;
            }
            byte[] buffer = Encoding.UTF8.GetBytes(packet.StringPacket);
            if (netinterface.AddressFamily == AddressFamily.InterNetwork)
            {
                try
                {
                    usession.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, netinterface.GetAddressBytes());
                    usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV4EndPoint);
                    usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV4EndPoint);
                }
                catch (SocketException ex)
                {
                    EventLogger.Log(ex);
                }
            }
            else if (netinterface.AddressFamily == AddressFamily.InterNetworkV6 && netinterface.ScopeId != 0)
            {
                try
                {
                    usession.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, BitConverter.GetBytes((int)netinterface.ScopeId));
                    if (netinterface.IsIPv6LinkLocal)
                    {
                        usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV6EndPoint2);
                        usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV6EndPoint2);
                    }
                    else
                    {
                        usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV6EndPoint1);
                        usession.Send(buffer, buffer.Length, Utils.UpnpMulticastV6EndPoint1);
                    }
                }
                catch (SocketException ex)
                {
                    EventLogger.Log(ex);
                }
            }
        }
예제 #13
0
        /// <summary>
        /// Pipelines a Uri request
        /// </summary>
        /// <param name="Resource">Uri to GET</param>
        /// <param name="Tag">State Data</param>
        public void PipelineRequest(Uri Resource, object Tag)
        {
            object[] Args = { Resource, Tag };

            string IP = Resource.Host;

            if (Resource.HostNameType == UriHostNameType.Dns)
            {
                Dns.BeginGetHostEntry(IP, GetHostByNameSink, Args);
            }
            else
            {
                ContinueRequest(
                    new IPEndPoint(IPAddress.Parse(Resource.Host), Resource.Port),
                    HTTPMessage.UnEscapeString(Resource.PathAndQuery),
                    Tag,
                    null);
            }
        }
예제 #14
0
        private void CreateSink(HTTPSession ss)
        {
            lock (TagQueue)
            {
                ss.OnHeader          += HeaderSink;
                ss.OnReceive         += ReceiveSink;
                ss.OnClosed          += CloseSink;
                ss.OnStreamDone      += StreamDoneSink;
                ss.OnRequestAnswered += RequestAnsweredSink;

                if (OnSniff != null)
                {
                    ss.OnSniff += SniffSink;
                }
                if (OnSniffPacket != null)
                {
                    ss.OnSniffPacket += SniffPacketSink;
                }

                StateData sd = (StateData)TagQueue.Peek();

                try
                {
                    if (ProxySetting == null)
                    {
                        ss.Send(sd.Request);
                    }
                    else
                    {
                        HTTPMessage pr = (HTTPMessage)sd.Request.Clone();
                        pr.DirectiveObj = "http://" + sd.Dest + pr.DirectiveObj;
                        pr.Version      = "1.0";
                        ss.Send(pr);
                    }
                }
                catch (Exception exc)
                {
                    EventLogger.Log(exc);
                }
            }
        }
예제 #15
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        private bool ValidateSearchPacket(HTTPMessage msg)
        {
            int MX;

            if (msg.GetTag("MAN") != "\"ssdp:discover\"")
            {
                return(false);                                          // { throw (new InvalidSearchPacketException("Invalid MAN")); }
            }
            if (msg.DirectiveObj != "*")
            {
                return(false);                         // { throw (new InvalidSearchPacketException("Expected * in RequestLine")); }
            }
            if (double.Parse(msg.Version, new CultureInfo("en-US").NumberFormat) < 1.1)
            {
                return(false);                                                                        // { throw (new InvalidSearchPacketException("Version must be at least 1.1")); }
            }
            if (int.TryParse(msg.GetTag("MX"), out MX) == false || MX <= 0)
            {
                return(false);                                                            // { throw (new InvalidSearchPacketException("MX must be a positive integer")); }
            }
            return(true);
        }
예제 #16
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        /// <summary>
        /// Unicast a HTTPMessage
        /// </summary>
        /// <param name="msg">The Packet to Unicast</param>
        public void UnicastData(HTTPMessage msg)
        {
            UdpClient usession = (UdpClient)usessions[msg.LocalEndPoint.Address];

            if (usession == null)
            {
                return;
            }
            if (OnSniffPacket != null)
            {
                OnSniffPacket(null, msg.RemoteEndPoint, msg);
            }
            byte[] buffer = msg.RawPacket;
            try
            {
                usession.Send(buffer, buffer.Length, msg.RemoteEndPoint);
            }
            catch (SocketException ex)
            {
                EventLogger.Log(ex);
            }
        }
예제 #17
0
        private void HeaderSink(HTTPSession sender, HTTPMessage header, Stream TheStream)
        {
            _Source = sender.Source;
            StateData sd;

            if (TheStream != null)
            {
                // This is the result of post-headers in a chunked document
                sd = (StateData)sender.StateObject;
                object Tag = sd.Tag;
                if (sd.HeaderCB != null)
                {
                    sd.HeaderCB(this, sender, header, TheStream, Tag);
                }
                sender.StateObject = null;
                KeepAliveTimer.Add(GetHashCode(), 10);
            }
            else
            {
                lock (TagQueue)
                {
                    sd = (StateData)TagQueue.Dequeue();
                }
                sender.StateObject = sd;
                object Tag = sd.Tag;
                if (sd.HeaderCB != null)
                {
                    sd.HeaderCB(this, sender, header, null, Tag);
                    if (sender.UserStream != null && !sender.IsChunked)
                    {
                        // If I don't set this to null, this holds a strong reference, resulting in
                        // possible memory leaks
                        sender.StateObject = null;
                    }
                }
            }
        }
예제 #18
0
 private void HandleHeader(HTTPSession sender, HTTPMessage Header, Stream StreamObject)
 {
     SessionTimer.Remove(sender);
     OnHeaderEvent.Fire(Header, sender);
 }
예제 #19
0
파일: SSDP.cs 프로젝트: talun2075/SonosAPI
        private void ProcessPacket(HTTPMessage msg, IPEndPoint src, IPEndPoint local)
        {
            if (OnSniffPacket != null)
            {
                OnSniffPacket(src, null, msg);
            }

            DText parser = new DText();

            parser.ATTRMARK = "::";

            bool   Alive = false;
            String UDN   = msg.GetTag("USN");

            parser[0] = UDN;
            String USN = parser[1];

            USN = USN.Substring(USN.IndexOf(":", StringComparison.Ordinal) + 1);
            String ST     = parser[2];
            int    MaxAge = 0;

            String NTS = msg.GetTag("NTS").ToUpper();

            if (NTS == "SSDP:ALIVE")
            {
                Alive = true;
                String ma = msg.GetTag("Cache-Control").Trim();
                if (ma != "")
                {
                    parser.ATTRMARK = ",";
                    parser.MULTMARK = "=";
                    parser[0]       = ma;
                    for (int i = 1; i <= parser.DCOUNT(); ++i)
                    {
                        if (parser[i, 1].Trim().ToUpper() == "MAX-AGE")
                        {
                            MaxAge = int.Parse(parser[i, 2].Trim());
                            break;
                        }
                    }
                }
            }

            if (msg.Directive == "NOTIFY" && OnNotify != null)
            {
                Uri    locuri   = null;
                string location = msg.GetTag("Location");
                if (location != null && location.Length > 0)
                {
                    try
                    {
                        locuri = new Uri(location);
                    }
                    catch (Exception ex)
                    {
                        EventLogger.Log(ex);
                    }
                }
                OnNotify(src, msg.LocalEndPoint, locuri, Alive, USN, ST, MaxAge, msg);
            }
            else if (msg.Directive == "M-SEARCH" && OnSearch != null)
            {
                if (ValidateSearchPacket(msg) == false)
                {
                    return;
                }
                int          MaxTimer   = int.Parse(msg.GetTag("MX"));
                SearchStruct SearchData = new SearchStruct();
                SearchData.ST     = msg.GetTag("ST");
                SearchData.Source = src;
                SearchData.Local  = local;
                SearchTimer.Add(SearchData, RandomGenerator.Next(0, MaxTimer));
            }
        }
예제 #20
0
        private void ContinueRequest(IPEndPoint dest, string PQ, object Tag, HTTPMessage MSG)
        {
            HTTPMessage r;

            if (MSG == null)
            {
                r              = new HTTPMessage();
                r.Directive    = "GET";
                r.DirectiveObj = PQ;
                if (dest.AddressFamily == AddressFamily.InterNetwork)
                {
                    r.AddTag("Host", dest.ToString());
                }
                if (dest.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    r.AddTag("Host", "[" + RemoveIPv6Scope(dest.ToString()) + "]");
                }
            }
            else
            {
                r = MSG;
            }

            lock (TagQueue)
            {
                IdleTimeout = false;
                KeepAliveTimer.Remove(GetHashCode());

                if ((PIPELINE == false && _PIPELINE == false) || (_PIPELINE == false))
                {
                    HTTPRequest TR = new HTTPRequest();
                    TR.ProxySetting = ProxySetting;
                    TR._PIPELINE    = true;
                    if (OnSniff != null)
                    {
                        TR.OnSniff += NonPipelinedSniffSink;
                    }
                    if (OnSniffPacket != null)
                    {
                        TR.OnSniffPacket += NonPipelinedSniffPacketSink;
                    }
                    TR.OnResponse        += NonPipelinedResponseSink;
                    NotPipelinedTable[TR] = TR;
                    TR.PipelineRequest(dest, r, Tag);
                    return;
                }

                TagQueue.Enqueue(new StateData(r, dest, Tag, null));

                IPAddress localif = IPAddress.Any;
                if (dest.AddressFamily == AddressFamily.InterNetworkV6)
                {
                    localif = IPAddress.IPv6Any;
                }

                if (s == null)
                {
                    ReceivedFirstResponse = false;
                    if (ProxySetting != null)
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                                            ProxySetting,
                                            CreateSink,
                                            CreateFailedSink,
                                            null);
                    }
                    else
                    {
                        s = new HTTPSession(new IPEndPoint(localif, 0),
                                            dest,
                                            CreateSink,
                                            CreateFailedSink,
                                            null);
                    }
                }
                else
                {
                    if (s.IsConnected && ReceivedFirstResponse)
                    {
                        try
                        {
                            if (ProxySetting == null)
                            {
                                s.Send(r);
                            }
                            else
                            {
                                HTTPMessage pr = (HTTPMessage)r.Clone();
                                pr.DirectiveObj = "http://" + dest + pr.DirectiveObj;
                                pr.Version      = "1.0";
                                s.Send(pr);
                            }
                        }
                        catch (Exception ex)
                        {
                            EventLogger.Log(ex);
                        }
                    }
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Parses a Byte Array at a specific location, and builds a Packet.
        /// </summary>
        /// <param name="buffer">The Array of Bytes</param>
        /// <param name="indx">The Start Index</param>
        /// <param name="count">The number of Bytes to process</param>
        /// <returns></returns>
        static public HTTPMessage ParseByteArray(byte[] buffer, int indx, int count)
        {
            HTTPMessage  TheMessage = new HTTPMessage();
            UTF8Encoding UTF8       = new UTF8Encoding();
            String       TempData   = UTF8.GetString(buffer, indx, count);
            DText        parser     = new DText();
            String       TempString;

            int idx = TempData.IndexOf("\r\n\r\n", StringComparison.Ordinal);

            if (idx < 0)
            {
                return(null);
            }
            TempData = TempData.Substring(0, idx);

            parser.ATTRMARK = "\r\n";
            parser.MULTMARK = ":";
            parser[0]       = TempData;
            string CurrentLine = parser[1];

            DText HdrParser = new DText();

            HdrParser.ATTRMARK = " ";
            HdrParser.MULTMARK = "/";
            HdrParser[0]       = CurrentLine;

            if (CurrentLine.ToUpper().StartsWith("HTTP/"))
            {
                TheMessage.ResponseCode = int.Parse(HdrParser[2]);
                int s1 = CurrentLine.IndexOf(" ", StringComparison.Ordinal);
                s1 = CurrentLine.IndexOf(" ", s1 + 1, StringComparison.Ordinal);
                TheMessage.ResponseData = UnEscapeString(CurrentLine.Substring(s1));
                try
                {
                    TheMessage.Version = HdrParser[1, 2];
                }
                catch (Exception ex)
                {
                    EventLogger.Log(ex);
                    TheMessage.Version = "0.9";
                }
            }
            else
            {
                TheMessage.Directive = HdrParser[1];
                TempString           = CurrentLine.Substring(CurrentLine.LastIndexOf(" ", StringComparison.Ordinal) + 1);
                if (TempString.ToUpper().StartsWith("HTTP/") == false)
                {
                    TheMessage.Version      = "0.9";
                    TheMessage.DirectiveObj = UnEscapeString(TempString);
                }
                else
                {
                    TheMessage.Version = TempString.Substring(TempString.IndexOf("/", StringComparison.Ordinal) + 1);
                    int fs = CurrentLine.IndexOf(" ", StringComparison.Ordinal) + 1;
                    TheMessage.DirectiveObj = UnEscapeString(CurrentLine.Substring(
                                                                 fs,
                                                                 CurrentLine.Length - fs - TempString.Length - 1));
                }
            }
            String Tag = "";

            for (int line = 2; line <= parser.DCOUNT(); ++line)
            {
                String TagData;
                if (Tag != "" && parser[line, 1].StartsWith(" "))
                {
                    TagData = parser[line, 1].Substring(1);
                }
                else
                {
                    Tag     = parser[line, 1];
                    TagData = "";
                    for (int i = 2; i <= parser.DCOUNT(line); ++i)
                    {
                        if (TagData == "")
                        {
                            TagData = parser[line, i];
                        }
                        else
                        {
                            TagData = TagData + parser.MULTMARK + parser[line, i];
                        }
                    }
                }
                TheMessage.AppendTag(Tag, TagData);
            }
            int cl;

            if (TheMessage.HasTag("Content-Length"))
            {
                try
                {
                    cl = int.Parse(TheMessage.GetTag("Content-Length"));
                }
                catch (Exception ex)
                {
                    EventLogger.Log(ex);
                    cl = -1;
                }
            }
            else
            {
                cl = -1;
            }

            byte[] tbuffer;
            if (cl > 0)
            {
                tbuffer = new byte[cl];
                if ((idx + 4 + cl) > count)
                {
                    // NOP
                }
                else
                {
                    Array.Copy(buffer, idx + 4, tbuffer, 0, cl);
                    TheMessage.DataBuffer = tbuffer;
                }
            }
            if (cl == -1)
            {
                tbuffer = new Byte[count - (idx + 4)];
                Array.Copy(buffer, idx + 4, tbuffer, 0, tbuffer.Length);
                TheMessage.DataBuffer = tbuffer;
            }
            if (cl == 0)
            {
                TheMessage.DataBuffer = new byte[0];
            }
            return(TheMessage);
        }
예제 #22
0
        /// <summary>
        /// Searches for a SearchTarget Asynchronously
        /// </summary>
        /// <param name="SearchTarget">The Target</param>
        public void FindDeviceAsync(String SearchTarget, IPEndPoint RemoteEP)
        {
            HTTPMessage request = new HTTPMessage();

            request.Directive    = "M-SEARCH";
            request.DirectiveObj = "*";
            request.AddTag("ST", SearchTarget);
            request.AddTag("MX", MX.ToString());
            request.AddTag("MAN", "\"ssdp:discover\"");
            if (RemoteEP.AddressFamily == AddressFamily.InterNetwork)
            {
                request.AddTag("HOST", RemoteEP.ToString());                                                       // "239.255.255.250:1900"
            }
            if (RemoteEP.AddressFamily == AddressFamily.InterNetworkV6)
            {
                request.AddTag("HOST", string.Format("[{0}]:{1}", RemoteEP.Address.ToString(), RemoteEP.Port));                                                         // "[FF05::C]:1900"
            }
            byte[] buffer = UTF8Encoding.UTF8.GetBytes(request.StringPacket);

            IPAddress[] LocalAddresses = NetInfo.GetLocalAddresses();

            foreach (IPAddress localaddr in LocalAddresses)
            {
                try
                {
                    UdpClient session = (UdpClient)SSDPSessions[localaddr];
                    if (session == null)
                    {
                        session = new UdpClient(new IPEndPoint(localaddr, 0));
                        session.EnableBroadcast = true;
                        session.BeginReceive(OnReceiveSink, session);
                        SSDPSessions[localaddr] = session;
                    }
                    if (RemoteEP.AddressFamily != session.Client.AddressFamily)
                    {
                        continue;
                    }
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal && RemoteEP != Utils.UpnpMulticastV6EndPoint2)
                    {
                        continue;
                    }
                    if ((RemoteEP.AddressFamily == AddressFamily.InterNetworkV6) && ((IPEndPoint)session.Client.LocalEndPoint).Address.IsIPv6LinkLocal == false && RemoteEP != Utils.UpnpMulticastV6EndPoint1)
                    {
                        continue;
                    }

                    IPEndPoint lep = (IPEndPoint)session.Client.LocalEndPoint;
                    if (session.Client.AddressFamily == AddressFamily.InterNetwork)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, localaddr.GetAddressBytes());
                    }
                    else if (session.Client.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        session.Client.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.MulticastInterface, BitConverter.GetBytes((int)localaddr.ScopeId));
                    }

                    session.Send(buffer, buffer.Length, RemoteEP);
                    session.Send(buffer, buffer.Length, RemoteEP);
                }
                catch (Exception ex)
                {
                    EventLogger.Log(this, EventLogEntryType.Error, "CP Failure: " + localaddr.ToString());
                    EventLogger.Log(ex);
                }
            }
        }
예제 #23
0
 private void HandleRequest(HTTPSession WebSession, HTTPMessage request)
 {
     OnReceiveEvent.Fire(request, WebSession);
 }
예제 #24
0
 /// <summary>
 /// Pipelines a request packet
 /// </summary>
 /// <param name="dest">Destination IPEndPoint</param>
 /// <param name="MSG">HTTPMessage Packet</param>
 /// <param name="Tag">State Data</param>
 public void PipelineRequest(IPEndPoint dest, HTTPMessage MSG, object Tag)
 {
     ContinueRequest(dest, "", Tag, MSG);
 }
        /// <summary>
        /// Triggered when a SSDP notification is received
        /// </summary>
        internal void SSDPNotifySink(IPEndPoint source, IPEndPoint local, Uri LocationURL, bool IsAlive, String USN, String SearchTarget, int MaxAge, HTTPMessage Packet)
        {
            UPnPDevice removedDevice = null;

            // Simple ignore everything that is not root
            if (SearchTarget != "upnp:rootdevice")
            {
                return;
            }

            if (IsAlive == false)
            {
                // The easy part first... we got a SSDP BYE message
                // Remove the device completely no matter what state it is in
                // right now. Also clear all clocks.
                lock (deviceTableLock)
                {
                    removedDevice = UnprotectedRemoveMe(USN);
                }
                if (removedDevice != null)
                {
                    removedDevice.Removed();
                    OnRemovedDeviceEvent.Fire(this, removedDevice);
                }
            }
            else
            {
                lock (deviceTableLock)
                {
                    // Ok, This device is annoncing itself.
                    if (deviceTable.ContainsKey(USN) == false)
                    {
                        // Never saw this device before
                        DeviceInfo deviceInfo = new DeviceInfo();
                        deviceInfo.Device     = null;
                        deviceInfo.UDN        = USN;
                        deviceInfo.NotifyTime = DateTime.Now;
                        deviceInfo.BaseURL    = LocationURL;
                        deviceInfo.MaxAge     = MaxAge;
                        deviceInfo.LocalEP    = local;
                        deviceTable[USN]      = deviceInfo;
                        deviceFactory.CreateDevice(deviceInfo.BaseURL, deviceInfo.MaxAge, local.Address, USN); // TODO2: Does URI construction work all this time??
                    }
                    else
                    {
                        // We already know about this device, lets check it out

                        DeviceInfo deviceInfo = (DeviceInfo)deviceTable[USN];
                        if (deviceInfo.Device != null) // If the device is in creation mode, do nothing
                        {
                            if (deviceInfo.BaseURL.Equals(LocationURL))
                            {
                                // Cancel a possible source change
                                deviceUpdateClock.Remove(deviceInfo);
                                deviceInfo.PendingBaseURL  = null;
                                deviceInfo.PendingMaxAge   = 0;
                                deviceInfo.PendingLocalEP  = null;
                                deviceInfo.PendingSourceEP = null;
                                // Then simply update the lifetime
                                deviceInfo.NotifyTime = DateTime.Now;
                                deviceTable[USN]      = deviceInfo;
                                deviceLifeTimeClock.Add(deviceInfo.UDN, MaxAge);
                            }
                            else
                            {
                                // Wow, same device, different source - Check timing
                                if (deviceInfo.NotifyTime.AddSeconds(10).Ticks < DateTime.Now.Ticks)
                                {
                                    // This is a possible source change. Wait for 3 seconds and make the switch.
                                    deviceInfo.PendingBaseURL  = LocationURL;
                                    deviceInfo.PendingMaxAge   = MaxAge;
                                    deviceInfo.PendingLocalEP  = local;
                                    deviceInfo.PendingSourceEP = source;
                                    deviceTable[USN]           = deviceInfo;
                                    deviceUpdateClock.Add(deviceInfo.UDN, 3);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #26
0
 private void HandleNotify(IPEndPoint source, IPEndPoint local, Uri LocationURL, bool IsAlive, String USN, String ST, int MaxAge, HTTPMessage Packet)
 {
     if (IsAlive && LocationURL != null)
     {
         EventLogger.Log(this, EventLogEntryType.SuccessAudit, LocationURL.ToString());
     }
     if (OnNotify != null)
     {
         OnNotify(source, local, LocationURL, IsAlive, USN, ST, MaxAge, Packet);
     }
 }