예제 #1
0
        public static async Task <StunMessage> Parse(Stream stream)
        {
            var header = new byte[20];
            await stream.ReadAsync(header, 0, 20);

            MessageMethod method = ParseMethod(header[0], header[1]);
            MessageClass  @class = ParseClass(header[0], header[1]);

            var length = new byte[2];

            System.Array.Copy(header, 2, length, 0, 2);

            var transactionId = new byte[12];

            System.Array.Copy(header, 8, transactionId, 0, 12);

            var body = new byte[length.ToUShort()];
            await stream.ReadAsync(body, 0, body.Length);

            IEnumerable <Attribute> attributes = ParseAttributes(
                body,
                transactionId
                );

            StunMessage rv = null;

            switch (@class)
            {
            case MessageClass.SuccessResponse:
                switch (method)
                {
                case MessageMethod.Allocate:
                    rv = new AllocateSuccessResponse();
                    break;

                case MessageMethod.Connect:
                    rv = new ConnectSuccessResponse();
                    break;

                case MessageMethod.ConnectionBind:
                    rv = new ConnectionBindSuccessResponse();
                    break;

                case MessageMethod.Binding:
                    rv = new BindingSuccessResponse();
                    break;

                case MessageMethod.CreatePermission:
                    rv = new CreatePermissionSuccessResponse();
                    break;

                case MessageMethod.Refresh:
                    rv = new RefreshSuccessResponse();
                    break;
                }

                break;

            case MessageClass.ErrorResponse:
                switch (method)
                {
                case MessageMethod.Allocate:
                    rv = new AllocateErrorResponse();
                    break;

                case MessageMethod.CreatePermission:
                    rv = new CreatePermissionErrorResponse();
                    break;

                case MessageMethod.Refresh:
                    rv = new RefreshErrorResponse();
                    break;
                }

                break;

            case MessageClass.Indication:
                switch (method)
                {
                case MessageMethod.ConnectionAttempt:
                    rv = new ConnectionAttempt();
                    break;
                }

                break;
            }

            if (rv != null)
            {
                rv.TransactionId = transactionId;
                rv.Attributes    = attributes;
            }

            return(rv);
        }