How to close an HTTP connection (which uses keep alive) from within a web application or a web service when there is no http request - wcf

I am writing a proxy application that runs on IIS 7.5 (could be a WCF web service or an MVC application) which forwards some data to another process on another server which doesn't run on IIS.
This following is the situation, where S1 is the server where the proxy must forward the data to and C1 is the client:
S1 --A-- [proxy] --B-- C1
The need for the proxy application is because we want to secure the connection A with 2-way SSL. And this can easily be configured in IIS.
Because of the 2-way SSL we want to use the keep alive option of HTTP 1.1.
If connection A is closed, the proxy needs to close connection B and vice versa. Connection A can also be closed after some time out after the last response has been sent.
My question is:
How can I close connection B after connection A is closed?
So in other words let the proxy send a TCP FIN to C1.
For the proxy application I can either use an asp.net MVC web site or a WCF web service.
The problem is that the response has already been sent to the client and there is no 'current http request' between C1 and the proxy, when connection A is closed after a timeout. So a call like this: HttpContext.Current.Response.Close() does not close connection B.
Thanks.

When you read EOS from the upstream socket, shutdown the downstream socket for output, and vice versa. When you do this, if you've already shutdown the socket that you read the EOS from, you've had EOS in both directions so you can close both sockets, and exit both threads if you're using threads. Let the actual decision as to when to close connections be taken by the downstream client and the upstream server.

Related

Is it normal for TCP request to randomly "get lost in the internet"?

I created and manage a SOAP API built in ASP.NET ASMX. The API processes about 10,000 requests per day. Most days, about 3 request sent by the client (we only have 1 client) do not reach the web server (IIS). There is no discernible pattern.
We are actually using 2 web servers that sit behind a load balancer. From the IIS logs, I am 100% confident that the requests are not reaching either web server.
The team that manages the network and the load balancer have not been able to 'confirm or deny' whether the problem is occurring at the load balancer. They suggested it's normal for request to sometimes "get lost in the internet", and said that we should add retry logic to the API.
The requests are using TCP (and TLS). The client has confirmed that there is no problem occurring on their end.
My question is: is it normal for TCP requests to "get lost in the internet" at the frequency we are seeing (about 3 out of 10,000 per day).
BTW, both the web server and the client are located in the same country. For what it's worth, the country in question is an anglopshere country, so it's not the case that our internet infrastructure is shoddy.
There is no such thing as a TCP request getting lost since there is no such thing as a TCP request in the first place. There is a TCP connection and within this there is a TLS tunnel and within this the HTTP protocol is spoken - and only at this HTTP level there is the concept of request and response which then is visible in the server logs.
Problems can occur in many places, like failing to establish the TCP connection in the first place due to no route (i.e. no internet) or too much packet loss. There can be random problems at the TLS level caused by bit flips which cause integrity errors and thus connection close. There can be problems at the HTTP level, for example when using HTTP keep-alive and the server closing an idle connection while at the same time the client is trying to send another request. And probably more places.
The client has confirmed that there is no problem occurring on their end.
I have no idea what exactly this means. No problem would be if the client is sending the request and getting a response. But this is obviously not the case here, so either the client is failing to establish the TCP connection, failing at the TLS level, failing while sending the request, failing while reading the response, getting timeouts ... - But maybe the client is simply ignoring some errors and thus no problem is visible at the clients end.

Debugging an SSL WebSocket that isn't running in a browser

I am trying to view the messages and communication of an SSL WebSocket server and client. The client is written in Java, so I could technically view the code with something like Recaf or JD-GUI, but I do not have access to the WS server. Is there any program that I could use to intercept the traffic of the client and server (Note: I am able to change the host, port, and protocol of the client's WS connection (like change it to ws://localhost:8080 from wss://server:port/path)).
Is there any program that can act as a non SSL WebSocket server, and then forward all connections to the remote server while logging the messages?

wsDualHttpBinding ClientBaseAddress & firewalls

I'm planning on using a wsDualHttpBinding for a WCF service with callbacks. The clients will be a windows form application communicating to the service over the internet. Obviously I have no control over the firewall on the client side, so I'm wondering what is the proper way to set the ClientBaseAddress on the client side?
Right now in my intiial testing I'm running the service and client on the same pc and i am setting the binding as follows
Dim binding As System.ServiceModel.WSDualHttpBinding = Struct.Endpoint.Binding
binding.ClientBaseAddress = New Uri("http://localhost:6667")
But I have a feeling this won't work when deploying over the internet because "localhost" won't translate to the machine address (much less worrying about NAT translation) and that port might be blocked by the clients firewall.
What is the proper way to handle the base address for callbacks to a remote client?
some one tell me if i do not specify ClientBaseAddress then WCF infratructure creates a default client base address at port 80 which is used for the incoming connections from the service. Since port 80 is usually open to firewalls, things should just work.
so just tell me when win form wcf client apps will run then how can i open my custom port like "6667" and also guide me what library or what approach i should use as a result response should come from client side router
to pc and firewall will not block anything. please discuss this issue with real life scenario how people handle this kind of situation in real life. thanks
The proper way is to use TCP transport instead of HTTP transport. Duplex communication over HTTP requires two HTTP connections - one opened from client to server (that's OK) and second opened from server to client. This can work only in scenarios where you have full control over both ends. There is simply too many complications which cannot be avoided just by guessing what address to use like:
Local Windows or third party firewall has to be configured
Permission for application to run - listening on HTTP is not allowed by default unless UAC is turned off or application is running as admin. You must allow listening on the port through netsh or httpcfg (windows XP and 2003) - that again requires admin permissions.
Port can be already used by another application. In case of 80 it can be used by any local web server - for example IIS.
Private networks and network devices - if your client machine is behind the NAT the port forwarding must be configured but what if you have two machines running your application on the same private network? You cannot forward from the same incoming port to two machines.
All these issues can be avoided mostly only when you have control over whole infrastructure. That is the reason why HTTP duplex communication is useful mostly for intranet scenarios and why for example Silverlight offers another implementation where the second connection is not created and Silverlight client instead polls server continuously to check if there is any callback available.
TCP transport requires only single connection from client to server because TCP protocol is natively duplex so the server can call back the client through the same connection. When you deploy a public service you usually have control over infrastructure on the server side so you can make necessary changes in configuration to make it work.
I think this also answers your previous question.

Specify client port (and IP) on NetTcpBinding

Is it not possible to specify the local client port used for server calls via NetTcpBinding?
NetPeerTcpBinding support this - I find it hard to believe there's no way to specify the local port (and IP Address for that matter) on clients.
I need to be able to use port sharing and I can't do this if I don't know what port the client is listening on. I won't be able to share the port (and IP) with another client so it can connect.
The only work-around I found is something like this:
Client A opens a connection to Server
Server logs the IP and Port of Client A
Server shares this info. with
Client B
Client B should be able to
connect to Client A on specified IP
and Port (in theory)
This is known as TCP/IP NAT hole punching I believe. Anyone with experience in this?
You probably don't understand the communication pattern with NetTcpBinding. It works this way:
The client opens connection to the server
Two-way communication: The client calls the server and gets the response over the same connection.
Duplex communication: The client calls the server. The server stores reference to the channel somewhere (you must implement this). Once the server wants to notify client about anything it takes stored channel and calls the client on the connection established by the client during its first call.
The server never opens connection to the client. The client doesn't expose any address with port for incomming communication. If you want to do that you must implement service on the client in the same way you did it on the server and you must manully send the address and port to the service exposed by the server.
The difference with NetPeerTcpBinding is that there is no real server and any client must be able to get incomming request. NetTcpBinding is for client-server scenarios where the server is the only peer able to process incomming requests. Because of that only the server needs to define an address and a port.

WCF + SSL wsDualHttpBinding or netTcpBinding

I need to create a self-hosted WCF service.
I need secure duplex connection between client and server through Internet.
I read some documents of WCF and found that the netTcpBinding is suitable for intranet application, because the SSL is only point 2 point. If it is an internet application, the connection must not be point 2 point, am I correct? so SSL in transport security with netTcpBinding is not suitable?
so what combination should I use to create a secure duplex internet application?
thank you very much.
I have tried http://www.codeproject.com/KB/WCF/WCFWPFChat.aspx
this tutorial use netTcpBinding and endpoint localhost
I change the endpoint localhost to a name based url, forward a port in my router to my development PC, open the same port at Windows firewall.
The client program can chat with each cients program in different machines, BUT the callback connection will lost after one minute.
I also tried changing the binding to wsDualHttpBinding, the clients program can chat with each clients in the same machine and kept the callback connection in the reliableSession inactivityTimeout setting. However another client program in another machine cannot join the server, if I turn off Windows firewall on that machine, the client program can connect.
It seems that tcp binding can let the client program connecting to the server with Windows firewall turn on. but callback connection lost.
and the wsDualHttpBinding can keep the callback connections. but cannot connect to server if Windows firewall on.
Is there a way to kept the netTcpBinding callback connection as in the wsDualHttpBinding?
It sounds like you have two issues- duplex connection and security.
If you truly need a duplex connection (eg, server-initiated callbacks), neither of these will work very well over the internet unless you have very fine control over the firewalls on both ends (the client still has to expose a publicly accessible HTTP endpoint for the server to call back). The best way would be to use the new relay services with .NET 4.0- this allows for a mimic'd server-initiated connection through firewalls.
EDIT: this is now called AppFabric, and is part of the Windows Azure infrastructure
On the security front, you can always use message security over the service bus, but I don't see a reason why transport security would be a problem either.
To answer user248724,
The client program can chat with each
cients program in different machines,
BUT the callback connection will lost
after one minute.after one minute.
You need either have the client or the server to ping each other at least every minute to keep the connection socket alive.