Nicholas Allen's Indigo Blog

Windows Communication Foundation From the Inside

January, 2007

  • Nicholas Allen's Indigo Blog

    Amplified Flooding Attacks

    • 2 Comments

    Today's article is about a classic flooding attack that relies on a receiver who isn't careful about where it sends responses. The whole article is about this next picture, so if you don't have images then you're going to miss out.

    The way that the attack works is that it relies on a receiver who sends replies or faults without having verified the reply address. In the normal case, replies go to some address that is controlled by the requestor. This is okay if we know who the requestor is and trust them.

    However, now suppose that we don't trust the requestor, perhaps because we've failed to authenticate them. An evil requestor can claim that replies should go off to some third-party address. There are a lot of systems where a very small request, remember it doesn't have to be valid at all, generates a much larger reply. In essence, the evil requestor is amplifying its attack power because it only needs the bandwidth for a 10 byte request to cause 1000 bytes to be thrown at the target machine.

    Stopping this attack is quite simple, although it can cause problems with the design of a distributed system. The receiver only sends replies to an address that is known to be owned by the requestor. That is a very simple rule to follow. If the requestor is authenticated, then the receiver trusts its claim of owning the reply address. If the requestor is not authenticated, then the receiver only sends replies along an associated back channel. Any replies that were supposed to be directed to any machine other than the requestor's are discarded. The attack is now stopped, although it breaks scenarios where the requestor wasn't authenticated but the requestor also wasn't being evil.

    Next time: Reducing Memory Usage with Large Messages

  • Nicholas Allen's Indigo Blog

    Queue Scalability

    • 4 Comments

    I'm building an always-on service that gets its messages from a front-end queue. How do I design this service to be scalable?

    There are two directions to go in when talking about scalability. There's scaling up, handling more messages while continuing to use a single machine, and then there's scaling out, handling more messages by using multiple machines. We'll talk about the two individually even though you may be using a combination of techniques to improve scalability.

    Scaling up is the simpler of the two although it isn't as interesting to talk about here. The WCF model works very naturally and automatically with scaling up. No matter how powerful the machine gets, it rarely makes sense to replicate an always-on service on a single machine. Rather than duplicating processes, single machine scalability in WCF is achieved by adding more threads to a single process. In other words, you'll get automatic scaling up until the point that you start hitting service model quota limits. This won't take long as the default service model limits are designed for a single processor machine with 10 concurrent clients. However, you can easily in the binding start increasing the number of threads pumping messages and the number of threads processing calls until you hit the hardware limitations of the machine. This is a balancing act to reach a point where resources are never idle, but they're also not overcommitted and facing contention.

    Scaling out involves replicating the server process to multiple machines. Typically the machines are tied together with network load balancing so that the distribution of load on the farm is controlled by the administrator rather than the user. Each of the machines needs their quotas tuned as above, although homogeneous hardware will let you get away with using a homogeneous binding on all of the machines. An asymmetric farm, with machines of varying capabilities, is really hard to tune.

    Queues come in to the picture because they generally favor scaling up rather than scaling out. Having a local queue has a number of advantages, including better transaction support unless you happen to be running a Vista or later operating system. However, it is generally much cheaper to scale out than scale up.

    A quick way to judge which way you need to scale next with your queue is to look at the bottlenecked resource. If you have exhausted the amount of network bandwidth you have moving messages out of the queue, then you should be thinking about moving the queues close to the service and scaling up. If you have exhausted the amount of computational power, either processing or disk, then you should be thinking about replicating the service to scale out and read from a remote queue. If clients are having trouble but you've maxed out neither your network nor computational power, then you probably need to go back and fix your quotas.

    Next time: Amplified Flooding Attacks

  • Nicholas Allen's Indigo Blog

    Using XML Serialization with WCF

    • 3 Comments

    How do I switch the serializer being used to process messages to the old XmlSerializer?

    WCF supports both the newer data contract style of message description as well as the older XmlSerializer style of message description used by ASP.NET. The recommended serializer for most uses and all new web service development is the data contract serializer.

    However, there are some good compatibility reasons why you may need to use the older XmlSerializer instead. Whenever you need to reuse existing types from an older ASMX application, from an existing XSD description, or other similar sources, the data contract serializer probably doesn't give you enough control to exactly match the existing type on the wire. The XmlSerializer on the other hand, gives you precise control over placement of the XML elements and attributes to craft the right message format.

    To find the serializer, the engine first examines the operation contract to see if any serializer has been specified. If not, the engine next examines the service contract to see if a serializer globally applies to all of the operations. If a serializer specification still hasn't been found, then the default data contract serializer is used. The easiest way to specify that you want to use the XmlSerializer is to annotate the service or operation contract with an attribute. We have the [XmlSerializerFormat] attribute that does exactly this for both operation and service contracts.

    Note that switching to the XmlSerializer is going to completely change how data contract types are interpreted. Data contracts only serialize type members that have been explicitly attributed as being members of the data contract. The XmlSerializer defaults to serializing every public member of the type. Therefore, you need to be careful when applying the XmlSerializerFormat attribute to make sure that the operations have been designed with that serialization method in mind.

    Next time: Queue Scalability

  • Nicholas Allen's Indigo Blog

    Disabling Security Timestamps

    • 2 Comments

    I'm using the WSHttp binding for message security with a non-WCF system. The other system doesn't have a complete security implementation, and in particular it doesn't know how to process message timestamps. How can I disable verification of the security timestamps in messages without turning off security?

    Timely delivery of data is always a concern in messaging systems. Security has a special interest in delivery times because short, expiring time windows are often very effective at limiting the attack surface of a message exchange. It is possible to disable the generation and checking of these timestamps, although you should be aware that doing so does leave your system a little less secure.

    Since I knew there was a setting for timestamp generation somewhere, I very quickly looked through the WSHttp binding to see if I could find it. When I couldn't find it on the binding, I simply went back to the binding elements and found it there on the security binding element. That means we can use our standard method for deriving a custom binding from one of the standard bindings.

    WSHttpBinding oldBinding = new WSHttpBinding();
    BindingElementCollection elements = oldBinding.CreateBindingElements();
    elements.Find<SecurityBindingElement>().IncludeTimestamp = false;
    CustomBinding newBinding = new CustomBinding(elements);

    Next time: Using XML Serialization with WCF

  • Nicholas Allen's Indigo Blog

    Errors Without Context

    • 1 Comments

    I don't know how many people use the code I post, but I frequently stumble across peculiar or interesting behavior while trying to get the snippets working. If the behavior relates to the topic I'm trying to explain, then it goes in the article. If the behavior is something off to the side, then I'll frequently plan to write a future article and end up never getting around to it. Today's article is actually from the IErrorHandler that I showed yesterday although it has nothing at all to do with the problem of changing HTTP status codes.

    Let's look at that error handler again with the addition of some debugging statements that I was trying to use.

    class HttpErrorHandler : IErrorHandler
    {
    public bool HandleError(Exception error)
    {
    Console.WriteLine(OperationContext.Current.IncomingMessageHeaders.To);
    return false;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    Console.WriteLine(OperationContext.Current.IncomingMessageHeaders.To);
    if (fault != null)
    {
    HttpResponseMessageProperty properties = new HttpResponseMessageProperty();
    properties.StatusCode = HttpStatusCode.PaymentRequired;
    fault.Properties.Add(HttpResponseMessageProperty.Name, properties);
    }
    }
    }

    Adding these debugging statements turns out to cause the service to fail in an unexpected way, which I thought was pretty interesting. I was only using ProvideFault last time, but I put the statements in both HandleError and ProvideFault. If you'll recall, ProvideFault was being used to modify the message fault as it was being generated. HandleError controls whether the exception at fault should result in the affected state being torn down. I return false from HandleError because this error handler definitely does nothing to handle the exception. The whole point of the example was to have things fail after all.

    If you run this code though, the debugging statement in ProvideFault works fine but the same statement in HandleError results in an ObjectDisposedException. By poking around, it turns out that between the time ProvideFault is called and HandleError is called, parts of the current message are already starting to go away. ProvideFault can safely use the OperationContext but that's not true for HandleError.

    Is there any practical implication of this behavior? Well, if your ability to handle errors depends upon some information in the message, then you're going to have a problem when it comes to HandleError. I don't know of a pleasant way to solve this. The unpleasant way to solve this is to read all of the information you need during ProvideFault and stash it somewhere so that you can get to it from HandleError. I expect you could use some extensible objects (I'll talk about those in a few weeks) or you could staple the information onto the exception that's being passed around. Neither alternative sounds very good.

    Next time: Disabling Security Timestamps

  • Nicholas Allen's Indigo Blog

    Modifying HTTP Error Codes, Part 2

    • 2 Comments

    Let's pick up where we left off last time with the question…

    How do I modify the HTTP status code that gets sent back with a fault?

    It's clear that we need to plug into the fault generation process somehow, but in past articles we've only seen fault handling for channels rather than services. Is there an equivalent for FaultConverter that we can use with our service? Well, partially. There's an IErrorHandler interface that very slightly overlaps the functionality of FaultConverter, but fortunately that's exactly the part we need. IErrorHandler allows us to replace the message faults that get created by the service. We can modify the status code by attaching a message property to the fault for the HTTP response. Here's what that looks like. I'll change the normal internal server error status code to one that indicates that the service requires payment to make the method call.

    class HttpErrorHandler : IErrorHandler
    {
    public bool HandleError(Exception error)
    {
    return false;
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    if (fault != null)
    {
    HttpResponseMessageProperty properties = new HttpResponseMessageProperty();
    properties.StatusCode = HttpStatusCode.PaymentRequired;
    fault.Properties.Add(HttpResponseMessageProperty.Name, properties);
    }
    }
    }

    Now, we need some way to attach this error handler to the service. Since this example is using IIS hosting, there are fewer points to hook in as we don't own the service host. I'll create a new server behavior attribute that attaches an IErrorHandler instance to the service. As IErrorHandler interfaces with the service dispatcher, I need to fish out the dispatchers from the service host.

    class ErrorBehaviorAttribute : Attribute, IServiceBehavior
    {
    Type errorHandlerType;

    public ErrorBehaviorAttribute(Type errorHandlerType)
    {
    this.errorHandlerType = errorHandlerType;
    }

    public void Validate(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
    }

    public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
    {
    IErrorHandler errorHandler;

    errorHandler = (IErrorHandler)Activator.CreateInstance(errorHandlerType);
    foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
    {
    ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
    channelDispatcher.ErrorHandlers.Add(errorHandler);
    }
    }
    }

    Once we attach the behavior attribute to the service from last time, we've completed the example.

    [ServiceContract]
    public interface IService
    {
    [OperationContract(Action = "*", ReplyAction = "*")]
    Message Action(Message m);
    }

    [ErrorBehavior(typeof(HttpErrorHandler))]
    public class Service : IService
    {
    public Message Action(Message m)
    {
    throw new FaultException("!");
    }
    }

    Let's telnet to the service address again and see what that did to the HTTP headers.

    HTTP/1.1 402 Payment Required
    Content-Type: application/xml; charset=utf-8
    Server: Microsoft-IIS/7.0
    X-Powered-By: ASP.NET
    Date: Wed, 10 Jan 2007 04:54:04 GMT
    Connection: close
    Content-Length: 159

    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Sender</Value></Code><Reason><Text xml:lang="en-US">!</Text></Reason></Fault>

    Exactly as expected, everything is the same except for the HTTP status code.

    Next time: Errors Without Context

  • Nicholas Allen's Indigo Blog

    Modifying HTTP Error Codes, Part 1

    • 2 Comments

    Back to errors and faults for a bit with this two part series on modifying the HTTP status code used for fault messages. First, we'll need some background.

    What happens at the HTTP level when a web service encounters a problem? That's a good question because it's not clear at all from programming the service what's going to happen under the covers. Let's build a service and find out. Here's the simplest web service I could think of that has a slight problem. I'll be hosting this in IIS so there's no other code needed to get going. You can imagine the configuration that goes along with this service, but I'm going to omit any discussion of that because it won't be relevant to anything we have to look at.

    [ServiceContract]
    public interface IService
    {
    [OperationContract(Action = "*", ReplyAction = "*")]
    Message Action(Message m);
    }

    public class Service : IService
    {
    public Message Action(Message m)
    {
    throw new FaultException("!");
    }
    }

    We can cut all the crud out of the messages by using a POX binding: a text encoder with MessageVersion set to None and a normal HTTP transport. Now, we can run this service and see what happens. I'm just going to telnet to the service address so that we can easily see all of the HTTP headers.

    HTTP/1.1 500 Internal Server Error
    Content-Type: application/xml; charset=utf-8
    Server: Microsoft-IIS/7.0
    X-Powered-By: ASP.NET
    Date: Tue, 10 Jan 2007 06:25:16 GMT
    Connection: close
    Content-Length: 159

    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none"><Code><Value>Sender</Value></Code><Reason><Text xml:lang="en-US">!</Text></Reason></Fault>

    This shows us that our service fault exception results in an HTTP status code of 500 for the response. The body of the message is something that looks a lot like a SOAP fault, but smaller because we said we weren't going to use SOAP. Inside the fault message you can see the fault elements that we talked about in past articles, and it's clear that we can modify anything inside the fault. It's not clear though what we modify to alter the framing of the HTTP response. That brings us to the actual question for this pair of articles.

    How do I modify the HTTP status code that gets sent back with a fault?

    We'll answer that question next time, which is going to require writing a bit more code.

    Next time: Modifying HTTP Error Codes, Part 2

  • Nicholas Allen's Indigo Blog

    Keeping Traces Up to Date

    • 2 Comments

    I've enabled tracing in my application, but I don't see entries in the trace log show up until I restart IIS. How can I get trace entries to appear right away?

    Like many other output files, traces are buffered to reduce the number of times that the disk has to be accessed to write out the data. It's possible that the trace log will be incomplete until something triggers writing out those traces that been buffered. This behavior impacts people differently depending on how they're debugging their applications. For instance, if you've got a self-hosted application that you're starting up, running a few tests, and shutting down, then this doesn't really impact you at all. Closing the application will write out the remaining traces.

    On the other hand, applications hosted in IIS tend to be impacted more. When hosting with IIS, you have less control about the lifetime of your application, including when it gets started and stopped. Even though you're done testing, IIS may be keeping your application alive and running, which prevents triggering the write out of remaining traces. You can work around this by restarting IIS and forcing everything to get shut down. However, if there are other applications running on the machine, then this can be painful.

    Another thing you can do is turn off the buffering of traces and take the slight performance hit of accessing the disk more frequently. Trace buffering (or really the lack of buffering) can be controlled through diagnostics configuration. This is another entry in the standard configuration file for your application, this time using the system.diagnostics namespace.

    <configuration>
    <system.diagnostics>
    <trace autoflush="true" />
    </system.diagnostics>
    </configuration>

    Next time: Modifying HTTP Error Codes, Part 1

  • Nicholas Allen's Indigo Blog

    Are Your Message Headers Still Unsecure?

    • 1 Comments

    Due to some server problems, the MSDN RSS and Atom feeds weren't getting updated Thursday or Friday. If your reader can't find the posts on securing custom message headers, then here are some direct links that you can use.

    Securing Custom Headers, Version 1

    Securing Custom Headers, Version 2

  • Nicholas Allen's Indigo Blog

    Securing Custom Headers, Version 2

    • 4 Comments

    Last time we were looking at the problem of securing a dynamically generated message header. We saw one solution to that problem, which was to add a behavior that updated the protection level for the desired message part. That solution is quite simple but it isn't perfect. The execution of this behavior comes rather late. Anyone that inspects the service description in the meantime, such as for metadata generation, won't see the protection level that we want to use.

    How early can we make the update to the security settings? Well, potentially very early. We could subclass ServiceHost and override ApplyConfiguration to make the changes during creation of the host. That may even be too early as it prevents us from working with anything that is added to the service description through code rather than configuration. However, we could similarly make the changes some time after we get the service host object back but before it was opened. This would let us plug in before any behaviors started execution. The choice is yours.

    The downside of this method is that it is a more treacherous route to get to the message header. Starting from the service host we need to get the endpoint that we're going to modify (usually by contract or address). From the endpoint we can get the operation by action name. From the operation we can get the right message by name. The default names are canonically derived from the operation action and direction. Unlike before, separating incoming and outgoing messages here is a lot murkier. From the message though, we can refer to the message header in the same way and set its protection level. Here's all of that in code using some example values.

    ServiceEndpoint endpoint = host.Description.Endpoints.Find(typeof(IService));
    OperationDescription operation = endpoint.Contract.Operations.Find("Action");
    MessageDescription message = operation.Messages.Find("http://tempuri.org/IService/ActionResponse");
    MessageHeaderDescription header = message.Headers[new XmlQualifiedName("aheader", "http://tempuri.org/")];
    header.ProtectionLevel = ProtectionLevel.Sign;

    Next time: Keeping Traces Up to Date

  • Nicholas Allen's Indigo Blog

    Securing Custom Headers, Version 1

    • 5 Comments

    I'm securing messages using SOAP security but I also have some message headers that are generated dynamically at runtime. How do I protect the generated message headers as well?

    If you've used SOAP security, then you've probably done it by decorating your messages with attributes that describe what the protection level is for various message parts. Obviously there's a problem here trying to take that approach with dynamically generated message headers. Since these message headers aren't a part of the declared message, there's nothing in the contract that you can decorate. We're going to look at two ways of solving this problem. For both articles, I'm only going to talk about protecting messages by signing. It is trivially easy to add encryption in if you want. The same is true for protecting headers on incoming versus outgoing messages as well.

    The first approach we're going to look at is to modify the security settings through binding parameters. The binding parameters contain the protection requirements of the contract. The protection requirements contain the list of headers. That gives us a two-step approach to accessing the list of headers. Since we need to change the protection requirements before the service is started, we'll insert a contract behavior to make the adjustments.

    public class SignMessageHeaderBehavior : Attribute, IContractBehavior
    {
    string action;
    string header;
    string ns;

    public SignMessageHeaderBehavior(string header, string ns, string action)
    {
    this.header = header;
    this.ns = ns;
    this.action = action;
    }

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    ChannelProtectionRequirements requirements = bindingParameters.Find<ChannelProtectionRequirements>();
    XmlQualifiedName qName = new XmlQualifiedName(header, ns);
    MessagePartSpecification part = new MessagePartSpecification(qName);
    requirements.OutgoingSignatureParts.AddParts(part, action);
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
    {
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
    }
    }

    Now, you've got a behavior that can at run time add a new message header to the list of signed headers. The action distinguishes which of the operations that you're talking about for that particular contract. Does this solution work? Yes. Is this the best solution? Maybe not. One issue that you may find troubling is that the behavior approach is too late to add the message header to the service description. If anyone looks at the WSDL, then they won't see the header, although if both the client and server are coordinated then this can work. Next time we'll look at a different approach that fixes this.

    Next time: Securing Custom Headers, Version 2

  • Nicholas Allen's Indigo Blog

    Faking Channel Security

    • 5 Comments

    I occasionally see people asking how they can fake the security capabilities of a binding. These questions often start off with "I'm getting an error message that a message's required protection level is not being met". Now, I'm not precisely sure why you'd want to fake the security capabilities in this case. After all, the application developer is in charge of both specifying the protection requirements of the messages and choosing what channels to use. If they're getting this error message, then it more than likely means that this helpful check has detected a problem somewhere in their design. There are a few rare reasons why you'd want to fake this, but they mainly involve transmitting over specially secured networks. However, it turns out that faking security capabilities is exactly the same as legitimately specifying the capabilities of a custom channel so I might as well explain that!

    Security capabilities are found by querying the channel stack with GetProperty for an instance of ISecurityCapabilities. This call should be supported on the binding element of channels that implement message or transport security. Transport channels should respond with something, even if it is to say that they don't support any kind of security. Everyone else can just delegate the call to their inner channel (which is typically what you do by default for any type you don't know about).

    public interface ISecurityCapabilities
    {
    ProtectionLevel SupportedRequestProtectionLevel { get; }
    ProtectionLevel SupportedResponseProtectionLevel { get; }
    bool SupportsClientAuthentication { get; }
    bool SupportsClientWindowsIdentity { get; }
    bool SupportsServerAuthentication { get; }
    }

    The fields here should be self-explanatory, you either support a particular feature or you don't, but let's look at examples from some of the existing channels.

    HTTP doesn't support any protection on requests and responses, neither encryption nor signing. HTTP supports client authentication when in any security mode but Anonymous. It only supports server authentication when using Negotiate security. Windows identities are supported whenever client authentication is.

    On the other hand, HTTPS provides both encryption and signing for both requests and responses. HTTPS always does server authentication. It supports client authentication and Windows identities whenever HTTP would plus whenever client certificates are turned on. You can quickly get a sense of the differences between HTTP and HTTPS by looking at these values.

    Message security is a little different because the channel needs to blend its capabilities with those of the underlying channel stack. For instance, messages are encrypted if either the security channel or any of the underlying channels performed that operation.

    Next time: Securing Custom Headers, Version 1

  • Nicholas Allen's Indigo Blog

    Restarting a Failed Service

    • 4 Comments

    I have an application hosted inside a Windows service that needs to be continuously running. Occasionally the application service host will fail and I have to restart the service. How can I automatically restart a failed service host?

    You may not find the advice I have to give here particularly helpful, but there are two important points that I'd like to get across.

    The first piece of advice is that there's no direct way to simply "restart" a service host. As pointed out in the communication lifecycle, once an object becomes faulted, it is dead and there's no way to bring it back to life. Instead, the only way to recover from a faulted service host is to abort the old one and throw it away. Then, you'll be able to create a new service host as a replacement to take over. You can hook the Faulted event on the service host to find out when you need to do this.

    The second piece of advice is that managing applications for continuous operation is very challenging. It is possible to build a host that will cleanly restart an application whenever necessary but you will spend a lot of time working on the host and not much time working on your application. IIS to a large extent is just a tool for starting, stopping, and restarting applications on demand. If that's the feature set you need, then why expend a lot of effort creating a new hosting environment that isn't going to be as good? There may be some bad reasons for choosing IIS as your hosting environment, but needing hosted application management is not one of them.

    Next time: Faking Channel Security

  • Nicholas Allen's Indigo Blog

    Customizing a Metadata Resolver

    • 2 Comments

    I'm trying to use a metadata resolver but the metadata endpoint requires a custom binding. How do I override the binding used by MetadataResolver?

    The overloads on MetadataResolver are pretty strange, but you can pick any of the ones that take an instance of MetadataExchangeClient.

    public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClient client, AsyncCallback callback, object asyncState);
    public static IAsyncResult BeginResolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode, MetadataExchangeClient client, AsyncCallback callback, object asyncState);
    public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, EndpointAddress address, MetadataExchangeClient client);
    public static ServiceEndpointCollection Resolve(IEnumerable<ContractDescription> contracts, Uri address, MetadataExchangeClientMode mode, MetadataExchangeClient client);

    Let's take the following ServiceHost as an example. It uses BasicHttpBinding for metadata exchange instead of one of the normal metadata endpoint bindings.

    ServiceHost host = new ServiceHost(typeof(Service), new Uri("http://localhost:8080"));
    host.AddServiceEndpoint(typeof(IService), new WSHttpBinding(), "servicedir/service");
    host.Description.Behaviors.Add(new ServiceMetadataBehavior());
    host.AddServiceEndpoint(typeof(IMetadataExchange), new BasicHttpBinding(), "mex");
    host.Open();

    Now, let's look at some code using MetadataResolver against this endpoint. We'll need to create a collection of contracts that includes IService. Also, we'll need to match the address and binding from the earlier service description.

    EndpointAddress address = new EndpointAddress("http://localhost:8080/mex");
    MetadataExchangeClient client = new MetadataExchangeClient(new BasicHttpBinding());
    List<ContractDescription> contracts = new List<ContractDescription>();
    contracts.Add(ContractDescription.GetContract(typeof(IService)));
    ServiceEndpointCollection endpoints = MetadataResolver.Resolve(contracts, address, client);

    Console.WriteLine(endpoints[0].Address);
    Console.WriteLine(endpoints[0].Binding);
    Console.WriteLine(endpoints[0].Contract.Name);

    You can run this to see what the metadata resolver is getting back from the endpoint.

    Next time: Restarting a Failed Service

  • Nicholas Allen's Indigo Blog

    Replacing an Existing ASMX Service with WCF

    • 6 Comments

    I have an existing ASMX service that I'm replacing with a WCF service. The replacement service works, but some of the clients point to a page with a service.asmx address. IIS gives me an error if I name my WCF service service.asmx. How do I get this to work?

    Sometimes big tasks get stuck on the tiniest of things. In this case, the task of porting a web service is getting stuck on what to call the resulting service file. Note that in most cases porting a service is not actually that hard either, although you will have to spend some quality time with the service contract fixing up namespaces and operation names to match what the old system automatically generated. That was a digression from the task at hand. Let's look at what's going wrong here and how to fix it.

    Service files are a text-based way to define the behavior that occurs when a resource with a particular address is requested. What actually goes on is that the resource file gets compiled to generate some code, and it's the file extension that decides what compiler gets used. A compiler is just an instance of System.Web.Compilation.BuildProvider that can spit out code on demand. You don't have to worry about any of this because we've already written a BuildProvider for WCF services. The class that does this is System.ServiceModel.Activation.ServiceBuildProvider although it may be hard to find any information about this class because it's not public. However, you also don't need to worry about that because for our purposes all you need to know is the type name.

    Now, the web.config file of your service controls the mapping of file extensions to a BuildProvider. Here's an example of changing the default mapping of *.asmx to invoke a WCF service.

    <system.web>
    <compilation>
    <buildProviders>
    <remove extension=".asmx"/>
    <add extension=".asmx" type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    </buildProviders>
    </compilation>
    </system.web>

    In case you're curious, here are the type names of a few of the other build providers that you normally have installed. There are more than a dozen of these on the typical system.

    • .aspx - System.Web.Compilation.PageBuildProvider
    • .asmx - System.Web.Compilation.WebServiceBuildProvider
    • .ashx - System.Web.Compilation.WebHandlerBuildProvider
    • .resx - System.Web.Compilation.ResXBuildProvider

    Next time: Customizing a Metadata Resolver

  • Nicholas Allen's Indigo Blog

    Serialization of Client Calls

    • 1 Comments

    I'm making multiple calls to a service and all of the other calls sit waiting until the first call completes. How do I make the service process multiple calls at the same time?

    If a service doesn't accept multiple, simultaneous calls from your client, then you have to figure out whether the problem is actually on the client or service.

    On the client side, what typically goes wrong here is that the first call blocks all other progress. After the first call completes, you can see multiple calls going out to the service. This is caused by the first call being responsible for opening the connection to the service. You can choose to either open a connection to the service manually by calling Open on the client, or otherwise the first call will automatically open a connection if there isn't one already. Until the connection to the server is established, none of the other calls can proceed and that causes the blocking behavior. The solution is to always open the client connection yourself ahead of time by calling Open so that this process is hopefully complete by the time you want to start making calls.

    If every call blocks, even after the first one, then this is probably due to the service configuration. There are two knobs that control whether multiple calls are allowed into the service called InstanceContextMode and ConcurrencyMode. You can set both of these knobs through a service behavior.

    InstanceContextMode controls how often we'll create a new instance. There will only ever be one context if you pick Single and there can be multiple contexts if you pick PerSession or PerCall. PerSession is probably the sweet spot but requires your channel stack to serve up sessionful channels, as from buffered TCP or from reliable messaging. It can be expensive to make your channel stack sessionful if it does not already support sessions from the protocols that you've picked.

    ConcurrencyMode controls how many threads we'll let into a service instance. There will only ever be one thread per instance if you pick Single or Reentrant, although Reentrant allows a thread to leave from a call and later come back in. There can be more than one thread per instance if you pick Multiple. You really don't have a choice about ConcurrencyMode because you either wrote the service to support multiple threads or you didn't. I don't see a compelling reason for your service to support multiple threads but restrict it to only have one.

    You should now be able to spot how InstanceContextMode and ConcurrencyMode can work together to either allow or prevent clients from making multiple calls.

    Next time: Replacing an Existing ASMX Service with WCF

  • Nicholas Allen's Indigo Blog

    MSMQ: Net vs Integration

    • 4 Comments

    Why are there two MSMQ bindings?

    This is an easy question to answer: there are two bindings for MSMQ because they do different things. Go ahead and take a look at each of the bindings. The NetMsmqBinding looks like a normal binding with an MSMQ transport, binary message encoder, and all of the normal features that you'd expect to find on a binding. On top of that, there a whole bunch of features that are specific to configuring a queue, like dead letter handling.

    The MsmqIntegrationBinding on the other hand looks totally different. Ok, the integration binding doesn't actually look all that different. All of the queue-specific features are shared between the two and that makes up a large portion of each of the bindings. However, the rest of the integration binding looks quite unusual compared to all of the standard bindings.

    • For instance, everything is wrapped into a single MSMQ integration binding element.
    • There's no message encoder or configuration of message features.
    • Addressing for messages with this binding element uses a very particular syntax.
    • There's no support for message security.
    • Actually, there's almost no support for composing the MSMQ integration binding element with any other type of protocol channel binding element, not just security channels.
    • You'll find that services using this binding are very limited in terms of contracts.

    The MsmqIntegrationBinding is intended for use with existing, already-written native MSMQ applications. The NetMsmqBinding is a lot better to use but only works if you have WCF on both ends of the queue. Therefore, one of these is always the clear choice for your queuing scenario depending on what's on the other side. There's nothing stopping you from hosting separate endpoints for each of these bindings at the same time if you need communication with both native and WCF clients. However, the two endpoints need to be kept with separate queues because the messages are not compatible.

    Next time: Serialization of Client Calls

  • Nicholas Allen's Indigo Blog

    Manual Addressing

    • 4 Comments

    How can a client application control the To address of an outgoing message? I don't want to create a new proxy for every connection.

    This is one of those topics that I could have sworn that I wrote about but can't find any evidence of it online. Actually, I was going through some papers the other day and found notes for five or six topics that got sketched out but never published. I'm guessing that that's what happened to the advice on manual addressing. In light of this discovery, today I'll focus solely on manual addressing from a service perspective and leave the channel perspective on manual addressing for another time.

    Manual addressing controls the stamping of addressing headers on outgoing messages. Normally, the transport just overwrites the message headers with whatever addressing information it's been configured with. No amount of fiddling at the service level will change that behavior because any existing addressing headers get obliterated when going through the transport.

    Some transports, such as HTTP, have a setting on the binding element called ManualAddressing that turns off this automatic stamping behavior. Other transports, such as TCP, will ignore your new header value with manual addressing because it's not possible to redirect an existing TCP connection on a per-message basis. This isn't a problem for HTTP because every HTTP request can have its own connection if desired. Support for manual addressing of messages is purely a transport-specific feature.

    The answer to the question therefore comes in three parts. First, make sure that the transport that you're using supports some form of manual addressing. If not, then you're out of luck in terms of sending messages to different destinations without creating some new object on a per-destination basis. Second, turn on that manual addressing option to prevent the automatic application of addressing headers during message sends. Third, use whatever method you want to apply your own addressing headers to the outgoing message. If you're just making service calls on a proxy, then you'll want to use something like this:

    OperationContext.Current.OutgoingMessageHeaders.To = this.replyTo.Uri;

    If you're creating Message instances yourself, then you'll want to apply your addressing headers to the message header collection and so on.

    Next time: MSMQ: Net vs Integration

    Update: I clarified what TCP's lack of support for manual addressing means.

  • Nicholas Allen's Indigo Blog

    Hosting on Machines with Multiple Addresses

    • 4 Comments

    I have a machine with multiple network cards. How do I control which networks my service listens on?

    The answer to this question is going to be specific to the transport that you're using. I'll cover the HTTP and TCP transports that WCF ships with. Talking about addresses for the named pipe transport is less interesting because we don't allow remote connections with our named pipes! With custom transports, you're on your own and will have to contact the author.

    The TCP transport is very liberal with wildcarding addresses. When given a choice of multiple addresses for a machine, it will listen on all of them. To change this, you need to prevent the transport from having this choice. Here are the two things that you will need to do. First, make sure that the HostNameComparisonMode property for the transport is set to Exact. HostNameComparisonMode controls the address wildcard and the Exact option means that the hostname and port have to match exactly. Second, change the listening address of the service from a hostname to an explicit IP address. This guarantees that you'll get the specific network address that you want. Now, you've removed all choice from matching the address of the service, and you have a service that only listens on a single one of your multiple addresses.

    The HTTP transport is a little bit more flexible with wildcarding because it can leverage a feature built into the platform for HTTP. The HTTP.SYS driver allows you to define an IP Listen List that contains a particular set of IP addresses to listen on for HTTP connections. If you don't have a listen list configured, then by default the HTTP transport will be listening on all of the available network addresses, exactly like the TCP transport. The same technique for listening on just a single address with HostNameComparisonMode works for HTTP as it did for TCP.

    Finally, I thought it important to mention that just about every computer these days has multiple IP addresses- even if you don't have multiple network cards. You have a loopback IP address (127.0.0.1 for IPv4) that always corresponds to local connections and a real IP address from your network adapter. This means that you have everything you need to craft a "local machine"-only service even when not using named pipes. The guarantee when doing this is a little bit weaker than the one we make for named pipes though. We block remote users that are going through a local intermediary from named pipes by filtering on the origin of the account login. These users will not be stopped by restricting a service to the loopback address.

    Next time: Manual Addressing

  • Nicholas Allen's Indigo Blog

    Designing New Faults

    • 5 Comments

    The last piece of this eleven part series on fault messages covers advice for channel authors that need to define their own set of faults. Everything here assumes that you're writing a protocol channel, that you have interesting failure cases that need to be acted on programmatically, and that your protocol does not overlap an existing protocol, such as security, reliable messaging, or transactions. By now, you should either be familiar with all of the classes involved with faults or going back to read the previous articles in the series.

    1. Basics of Failure
    2. Creating Faults, Part 1
    3. Creating Faults, Part 2
    4. Creating Faults, Part 3
    5. The Most Distinguished Fault
    6. A Historical, Awkwardly Named Fault
    7. Consuming Faults, Part 1
    8. Consuming Faults, Part 2
    9. Zen Faults
    10. Faults and HTTP

    Let's start with the basic definition of a SOAP fault. It's mandatory to have a fault action, fault code, and fault reason. The fault detail is optional.

    The fault action is the first round of filtering performed on faults and so you should define an action that is unique to your protocol. Every fault that you create for the protocol should have this same action. Following this rule helps you and everyone else quickly sort out the faults that you need to handle and let everything else go up to the next protocol layer.

    The fault code should be unique to each expected type of recovery action. For instance, if you have two faults that you need to programmatically handle in a different fashion, then those faults should have different fault codes. If you have two faults that are semantically the same, then those faults should have the same fault code but different fault reasons.

    Every fault should have its own descriptive fault reason that explains why the fault occurred and what the user should do. Fault reasons are localizable if you're translating your application into multiple languages.

    The final piece is the fault detail, which you should only provide if you have some extra information that hasn't been covered by one of the previous parts.

    Your channel should throw exceptions when an error occurs, following the standard rules for exceptions in a CommunicationObject, such as using subtypes of CommunicationException or TimeoutException. The granularity of new exception subtypes should be similar to the granularity of new fault codes. Your channel then needs to override GetProperty<FaultConverter> to provide a converter that translates back and forth between exceptions and fault messages. Your converter should delegate to the default system FaultConverter if it is unable to handle the fault or exception.

    Following this process, you should not be using FaultException to wrap faults. Intermediate exception handlers can process your custom exception classes but don't know enough to be able to pull information out of a wrapped fault. You should also find by doing this that there are only limited uses for providing a fault detail.

    Next time: Hosting on Machines with Multiple Addresses

  • Nicholas Allen's Indigo Blog

    Faults and HTTP

    • 2 Comments

    I left HTTP error codes out of yesterday's post on zen faults because they're representative of a distinct class of out-of-band fault messages. Out-of-band faults map fault information to a transport-specific mechanism that carries the data outside of the normal message payload. Although we don't send a regulation SOAP fault message, there's still a clear concept of a message and the other side doesn't have to rely on intuition to know that a fault took place.

    In the case of HTTP, the first line of a response contains status information that can be used to signify an error. There is a tradeoff to using this mechanism because SOAP faults are significantly richer than HTTP status codes while HTTP status codes are much more broadly understood by devices and programs. The status codes we care about lay in the 400 and 500 ranges. Codes in the 400 range are used for client errors and codes in the 500 range are used for server errors. Code 400 represents a generic error with the client request with additional definitions for codes 401 through 417. Similarly, code 500 represents a generic error happening on the server with additional definitions for codes 501 through 505.

    A code 400 error would represent something like an uninterpretably mangled request message. The common code 404 (Not Found) error represents EndpointNotFound while the much less common code 415 error (Unsupported Media Type) represents an InvalidContentType for the SOAP message.

    A code 500 error would represent something like a catastrophic service error, such as the code for the service can't be compiled. The only other common server error is code 503 (Service Unavailable). Code 503 errors typically represent unavailability due to server load, roughly the equivalent of ServerTooBusy.

    Next time: Designing New Faults

  • Nicholas Allen's Indigo Blog

    Zen Faults

    • 3 Comments

    I've been talking about fault messages for a while now, specifically the kind that are sent around as the body contents of a SOAP message. However, some of the most important faults are reported without sending a message at all. In that case, we have to intuit that a fault has occurred based on the other sources that we can observe. I'll cover a special case of these zen faults, faults over HTTP status codes, tomorrow. There are plenty of examples of such faults that don't involved HTTP though. How are faults transmitted without sending messages? And, why do we do this?

    Throughout this post I'm assuming that we're just talking about faults in the underlying system. There are plenty of ways for applications to zen fault the other side through ungraceful shutdowns or arbitrary behavior. This is especially caused by Abort, which simply disposes of all network resources without bothering to clean up after itself (certain protocol channels, such as transactions, may attempt to salvage the situation but that's another matter).

    The zen fault that most everyone has probably seen is an EndpointNotFound. We sometimes have to intuit that fault based on a connection being closed or refused. Occasionally, the endpoint has legitimately gone missing. Frequently though, our intuitive guess about the fault is wrong. More likely problems are an error in configuration, the presence of firewalls, or the server simply being too busy to accept the connection in time. All of these situations can make it look like a service isn't running at all.

    Another common zen fault is the result of a quota being exceeded. Quota faults often manifest themselves as "Remote connection aborted" type errors. The other side has decided that it has spent too many resources on this connection and doesn't want to spare any more sending back a fault message. The client has little or no indication of what went wrong as there's no way to determine why the server closed the connection. This type of fault is basically indistinguishable from an arbitrary call to Abort. In order to diagnose the fault successfully, you need to look at trace logs on the server where notice of the quota exception is recorded. You may be hinted to the presence of a quota fault by the problem occurring reliably at "round" numbers, such as 60 seconds, 65536 bytes, or 10 connections.

    The last type of common zen fault occurs when there's a fault prior to the caller's identity being verified (for instance, if the identity verification failed). We can return a fault if there's a back channel that will direct the message to the original sender. However, we don't want to initiate new connections because that could send the fault to a location using unverified data. There have been a lot of historical flooding attacks based on evil machine A sending a small payload to unsuspecting server B which then sends a large error message to target machine C.

    Next time: Faults and HTTP

  • Nicholas Allen's Indigo Blog

    2006 Year in Review

    • 3 Comments

    I started this blog back in February hoping to produce a daily post throughout the entire month. I had about twenty topic ideas ready and I had no idea what I was going to do when those ran out. The long-term goal was to reach 100,000 visitors a month by the end of the year. Well, I'm glad to say that since then there has been no danger at all of running out of topics.

    Through the last day of December, I had a post queued up for every non-holiday working day along with several bonus posts for a total of 250 posts during the year. Almost all of the queued posts made it up successfully, a few server upgrades and power failures excepting. June was the first month with more than 100,000 visitors and the typical month now sees several times that.

    It's tough to get a true count of exactly how much writing that equates to. I type all of the posts in Word before publishing and running a count across all of those documents says that I've used 99,349 words (from 555,536 characters or roughly 5.6 characters per word). Given that I've updated quite a few posts with additional text since posting, the total count breaks 100,000 words by that metric. However, I think that count is bogus because of all the code samples and output text. I try to make posts between 300 and 500 words every day, so an average of 400 words per article is believable but probably too high. The right ballpark figure is probably 80,000-85,000 words for the year plus a few thousand lines of code.

    Speaking of words, the longest posts of original, non-code content have been from the documentation series:

    Configuring WCF for NATs and Firewalls (1,446 words)

    Choosing a Transport (1,439 words)

    Making Sense of Transport Quotas (1,296 words)

    This whole series has been among the most popular posts as well, although here is a selection from other categories that have also been popular as measured over the last month (December posts excluded):

    Inside the Standard Bindings: NetTcp (Bindings champion)

    Pull Not Push (Service Architecture runner-up)

    Configuring HTTP for Windows Vista (Answers champion among several other categories)

    Net.Tcp Port Sharing Sample, Part 1 (Samples champion)

    Building a Custom File Transport, Part 1: Planning (Channel Extensibility champion)

    There's no end in sight for blogging in 2007 although I still have to make good on producing a working table of contents. I hope to try that and start editing some of the multi-part series into a single cohesive post within the next few months. This week is going to finish out the series on faults. Next week it will be time again to dip into topics from reader mail for a while.

    Next time: Zen Faults

Page 1 of 1 (23 items)