Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have an application that listens for connections on a port, but I occasionally take it down for updates and the like. I'd like a way to configure the system such that if that program is running, requests for that port are sent to the application, but if it's not running the requests are directed to some other application (that can return a "temporarily unavailable" message). What's the easiest way to accomplish that?

I don't have root access on the target machine, so I'd prefer to avoid things like iptables. I've considered a helper application that does nothing but route connections to the other two applications, but I'm hoping there's an easier way

share|improve this question
    
How do you normally start and stop your main application? Seems to me the simplest approach is to modify that routine to also stop and start your helper application (which listens on the same port). –  jw013 Apr 16 '12 at 21:07
add comment

1 Answer

up vote 6 down vote accepted

Your question implies that both programs would be running in alternation on the same machine, bound to the same port. This is a bad idea. You will run into the TIME_WAIT (a.k.a. 2MSL) problem if you try this. This article describes the problem. (It's Windows-centric, but most of what it's talking about applies to any TCP/IP stack.)

The BSD sockets API does provide a way to defeat this protection (setsockopt(SO_REUSEADDR)), but this is not one of the cases where doing so is justified.

Instead, solve the problem the same way the High Availability folk do: put a reverse proxy between the world and your "real" back-end server.

In the HTTP world, one popular solution to this problem is nginx. You can configure it so that while the back end server is down, it serves static content to clients. If your protocol looks like HTTP, IMAP or POP, maybe you can use nginx as-is. If not, you could build a custom proxy server.

You probably need two TCP ports for this to work. The proxy binds to the public-facing port number, on the public IP. Your back-end server binds to a secondary port, on the localhost interface only. Thus, traffic can get from the public network to the back-end server only through the proxy.

You can get away with binding both to the same port if both programs are written to allow it. For instance, if your public IP is 1.2.3.4 and your public service port is 2345, both programs can bind to port 2345 if the reverse proxy binds only to IP 1.2.3.4 and the "real" server binds only to 127.0.0.1. If either binds to INADDR_ANY (0.0.0.0) you need different ports.

This solves the 2MSL problem because your clients are always talking to the same program, the proxy server. The network stack won't ever be confused about what to do with any stray packets swept up in the 2MSL time.

A variation on the reverse proxy is the load balancer, and it could also work here. A load balancer is designed to intelligently route traffic to different machines. This sort of proxy would make sense if you thought your app might someday need to scale horizontally. You'd select a load balancer that knows how to send traffic to a special "service down" host when all the normal application servers are down.

The main problem the load balancer solution variant is that a generic load balancer might blindly assume that all back-end services it proxies for are using the same port number, differing only in IP. You might be able to get a more flexible load balancer, or get multiple IPs for your shared server, though.

share|improve this answer
    
Upvoted. To add a little, he's better off using an init script that starts the other app when his app isn't running, and stops it when it is. –  laebshade Apr 17 '12 at 3:37
    
@laebshade: I don't know why you post that as a comment to my answer. You're saying pretty much the opposite of what I am, so it would seem you have a different solution. With a reverse proxy, both programs stay running in normal operation. When the "real" server goes down, the proxy stays up, either redirecting traffic to a fallback server (load balancer type) or sending out some kind of fall-back content (transparent proxy type). Are you sure you understand the 2MSL problem? –  Warren Young Apr 17 '12 at 4:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.