Represents an exception-safe wrapper of the .NET socket class. It exposes asynchronous methods and properties useful for state server soket operations.
The .NET Socket class is thread-safe but you can never be too careful. This class introduces an extra synchronization layer.
コード例 #1
0
ファイル: Diags.cs プロジェクト: zofuthan/p2pStateServer
 static public void LogSend(ServiceSocket socket, ResponseData Response)
 {
     Debug.WriteLine("[" + GetFormattedTime(DateTime.Now) + "] " + string.Format("Sent {0} to {1}\n", Response.ResponseType.Name, socket.RemoteIP), "MESSAGING");
 }
コード例 #2
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        /// <summary>
        /// Sends a CompleteAuthRequest message to a specified ServiceSocket.
        /// </summary>
        /// <param name="Nonce">The nonce field value in the Authorization Request Header, according o RFC 2617</param>
        /// <param name="ClientNonce">The cnonce field value in the Authorization Request Header, according o RFC 2617</param>
        /// <param name="ServerDigest">The response field value in the Authorization Request Header, according o RFC 2617</param>
        /// <param name="ClientDigest">The calculated Client Digest</param>
        /// <param name="SessionKey">The calculated data encryption session key</param>
        /// <param name="MachineName">The computer's name. Used as the username field value in the Authorization Request Header, according to RFC 2617</param>
        /// <param name="Algorithm">The algorithm field value in the Authorization Request Header, according o RFC 2617</param>
        /// <param name="Realm">The realm field value in the Authorization Request Header, according o RFC 2617</param>
        /// <param name="socket">The target ServiceSocket</param>
        public static void Send(string Nonce, string ClientNonce, string ServerDigest, string ClientDigest, byte[] SessionKey, string MachineName, string Algorithm, string Realm, ServiceSocket socket, string ServerIP)
        {
            string msg = string.Format("GET \\AUTH HTTP/1.1\r\nHost: {0}\r\nAuthorization: Digest username = \"{1}\", realm=\"{2}\" , nonce=\"{3}\", uri =\"\\AUTH\",qop=\"auth\",nc=1,cnonce=\"{4}\" ,response=\"{5}\",algorithm=\"{6}\"\r\n\r\n"
            , ServerIP ?? socket.LocalIP, MachineName, Realm, Nonce, ClientNonce, ServerDigest, Algorithm);

            /*
             * SAMPLE:
             *
                GET \AUTH
                Host: localhost
                Authorization: Digest username = "******", realm="state_service@PC-2" , nonce="NjMzODI1MzkyOTQ2NDA2MjUwOjE2ZjMwOTUx", uri ="\AUTH",qop="auth",nc=1,cnonce="NjMzODI1MzY5NzQ2ODc1MDAwOjcwZGQ0YWM5" ,response="10e10310780d80460c30f403801703f08b08c0d606807905c06d0140d70ff08e06404c0b30150130a501b0210720fa02",algorithm="SHA-256"
             *
             */

            string[] refobject = new string[3];

            /*      Reference object is an object array:
             *
             *        Array[0] = cnonce
                      Array[1] = clientdigest
                      Array[2] = sessionkey
             *
             */

            refobject[0] = ClientNonce;
            refobject[1] = ClientDigest;
            refobject[2] = Convert.ToBase64String(SessionKey);

            ResponseData data = new ResponseData(Encoding.UTF8.GetBytes(msg), typeof(CompleteAuthRequest));
            data.Tag = refobject;

            socket.Send(data);
            Diags.LogSend(socket, data);
        }
コード例 #3
0
ファイル: Diags.cs プロジェクト: tenor/p2pStateServer
 public static void LogSend(ServiceSocket socket, ResponseData Response)
 {
     Debug.WriteLine( "[" + GetFormattedTime(DateTime.Now) + "] " + string.Format("Sent {0} to {1}\n", Response.ResponseType.Name, socket.RemoteIP), "MESSAGING");
 }
コード例 #4
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        /// <summary>
        /// Sends a PingReplyMessage message to a specified ServiceSocket
        /// </summary>
        /// <param name="socket">The target ServiceSocket</param>
        /// <param name="ASPNETVersion">The state server version</param>
        public static void Send(ServiceSocket socket, string ASPNETVersion)
        {
            ResponseData rdata = new ResponseData(Encoding.UTF8.GetBytes("200 OK\r\nX-AspNet-Version: " + ASPNETVersion + "\r\nServer: State Service Peer\r\nContent-Length: 0\r\n\r\n"), typeof(PingReplyMessage));

            socket.Send(rdata);
            Diags.LogSend(socket, rdata);
        }
コード例 #5
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        /// <summary>
        /// Sends a PingMessage message to a specified ServiceSocket
        /// </summary>
        /// <param name="socket">The target ServiceSocket</param>
        public static void Send(ServiceSocket socket, string ServerIP)
        {
            ResponseData rdata = new ResponseData(Encoding.UTF8.GetBytes("GET \\PING HTTP/1.1\r\nHost: " + (ServerIP ?? socket.LocalIP) + "\r\nContent-Length: 0\r\n\r\n"), typeof(PingMessage));

            socket.Send(rdata);
            Diags.LogSend(socket, rdata);
        }
コード例 #6
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        //Timeout action needs to be very short as it can be chained in a long call list of time out actions
        /// <summary>
        /// Sends a BeginAuthRequest message to a specified ServiceSocket
        /// </summary>
        /// <param name="socket">The target ServiceSocket</param>
        /// <param name="Service">The state server instance</param>
        /// <param name="SuccessAction">The Action to call if the message was accepted</param>
        /// <param name="FailAction">The Action to call if the message transmission failed or was refused</param>
        /// <param name="TimeoutAction">The Action to call if the transfer timed out This Action's processing time should be very short because a long list of Timeout actions can be daisy-chained and called one after the other</param>
        /// <param name="Timeout">The timeout time span</param>
        public static void Send(ServiceSocket socket, StateServer Service, Action<ServiceSocket> SuccessAction, Action<ServiceSocket> FailAction, System.Threading.WaitCallback TimeoutAction, TimeSpan Timeout)
        {
            ResponseData rdata = new ResponseData(Encoding.UTF8.GetBytes("GET \\AUTH HTTP/1.1\r\nHost: " + (Service.ServerIP ?? socket.LocalIP) + "\r\n\r\n"), typeof(BeginAuthRequest));

            //Create new AsyncResultActions object to hold delegates for actions based on the outcome of the call
            AsyncResultActions<ServiceSocket> asyncResults = new AsyncResultActions<ServiceSocket>(socket);
            asyncResults.Result1Action = SuccessAction;
            asyncResults.Result2Action = FailAction;
            asyncResults.TimeoutAction = TimeoutAction;

            Service.AsyncSocketRequests.Add(DateTime.UtcNow + Timeout, socket, asyncResults);

            socket.Send(rdata);
            Diags.LogSend(socket, rdata);
        }
コード例 #7
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        int totalLength; //total length of received information

        #endregion Fields

        #region Constructors

        //TODO: FEATURE: PIPELINING: Add a new feature for pipelining called "RemainingData","FalloverData","NextMessagePrefix" or something similar to report data to Prefix the next message on this socket
        /// <summary>
        /// Initializes a new instance of the HTTPPartialData class
        /// </summary>
        /// <param name="HandlerSocket">The associated socket</param>
        public HTTPPartialData(ServiceSocket HandlerSocket)
        {
            handler = HandlerSocket;

            lines = new List<byte[]>();
            content = null;
            bufferedLine = new byte[MaxLineLength];
            totalLength = 0;
            contentLength = null;
            bufferPos = -1;
            isError = false;
            isComplete = false;
            contentlengthMode = false;
        }
コード例 #8
0
ファイル: Messages.cs プロジェクト: tenor/p2pStateServer
        /// <summary>
        /// Initializes a new instance of the HTTPMessage class
        /// </summary>
        /// <param name="Data">The HTTPPartialData class to load this instance from</param>
        /// <param name="Service">State server instance</param>
        public HTTPMessage(HTTPPartialData HTTPData)
        {
            if (HTTPData.IsError)
            {
                throw new ArgumentException("HTTP Partial data has an error", "HTTPData");
            }

            if (!HTTPData.IsComplete)
            {
                throw new ArgumentException("HTTP Partial data is not complete", "HTTPData");
            }

            socket = HTTPData.HandlerSocket;
            byte[][] lines = HTTPData.Lines;

            if (lines.Length == 0)
            {
                isError = true;
            }
            else
            {
                requestStatusLine = Encoding.UTF8.GetString(lines[0], 0, lines[0].Length - 2); //compensate for CRLF
            }

            //Get HTTP Method Information
            try
            {
                verb = new HTTPMethod(requestStatusLine);
            }
            catch
            {
                isError = true;
                verb = null;
            }

            //Get Headers
            for (int i = 1; i < lines.Length; i++)
            {
                byte[] line = lines[i];
                if (line.Length > 2) //skip CRLF-only lines
                {
                    int index = Array.IndexOf(line, (byte)58);//':' character

                    if (index < 1)
                    {
                        isError = true;
                        continue;
                    }

                    string name = Encoding.UTF8.GetString(line, 0, index);
                    string value = string.Empty;

                    if (index < (line.Length - 3)) //compensate for CR and LF
                    {
                        value = Encoding.UTF8.GetString(line, index + 1, line.Length - (index + 3));
                    }

                    headers.Add(name.Trim().ToUpperInvariant(), value.Trim());
                }

            }

            //Get Body Data
            body = HTTPData.Content == null ? new byte[0] { } : HTTPData.Content;

            //Pickup Host
            host = headers["HOST"];
            if (host == null && verb.Type == HTTPMessageType.Request)
            {
                isError = true;
            }

            //look for Content-Length and compare it with body length

            string cLen = headers["CONTENT-LENGTH"] ;
            if (cLen == null || cLen.Trim() == string.Empty)
            {
                if (body.Length != 0) isError = true;
            }
            else
            {
                int v;
                if (int.TryParse(cLen, out v))
                {
                    if (v != body.Length) isError = true;
                }
                else
                {
                    isError = true;
                }

            }
        }