Skip to content

Commit 31d1588

Browse files
committed
Add a special vhost for health checking that uses /etc/nolvs
Also adds another special vhost for debugging/monitoring
1 parent e0f8cfa commit 31d1588

File tree

2 files changed

+85
-6
lines changed

2 files changed

+85
-6
lines changed

server/common/oursrc/scripts-proxy/main.go

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ func always(context.Context, string) bool {
2828
}
2929

3030
type ldapTarget struct {
31-
localPoolRange *net.IPNet
32-
ldap *ldap.Pool
31+
localPoolRange *net.IPNet
32+
ldap *ldap.Pool
33+
statuszServer *HijackedServer
34+
unavailableServer *HijackedServer
3335
}
3436

3537
// HandleConn is called by tcpproxy after receiving a connection and sniffing the host.
@@ -39,6 +41,17 @@ func (l *ldapTarget) HandleConn(netConn net.Conn) {
3941
var pool string
4042
var err error
4143
if conn, ok := netConn.(*tcpproxy.Conn); ok {
44+
switch conn.HostName {
45+
case "proxy.scripts.scripts.mit.edu":
46+
// Special handling for proxy.scripts.scripts.mit.edu
47+
l.statuszServer.HandleConn(netConn)
48+
return
49+
case "heartbeat.scripts.scripts.mit.edu":
50+
if nolvsPresent() {
51+
l.unavailableServer.HandleConn(netConn)
52+
return
53+
}
54+
}
4255
pool, err = l.ldap.ResolvePool(conn.HostName)
4356
if err != nil {
4457
log.Printf("resolving %q: %v", conn.HostName, err)
@@ -50,9 +63,9 @@ func (l *ldapTarget) HandleConn(netConn net.Conn) {
5063
log.Printf("resolving default pool: %v", err)
5164
}
5265
}
53-
// TODO: Serve an error page? Forward to scripts-director?
66+
// TODO: Forward to sorry server on director?
5467
if pool == "" {
55-
netConn.Close()
68+
l.unavailableServer.HandleConn(netConn)
5669
return
5770
}
5871
laddr := netConn.LocalAddr().(*net.TCPAddr)
@@ -91,8 +104,10 @@ func main() {
91104

92105
var p tcpproxy.Proxy
93106
t := &ldapTarget{
94-
localPoolRange: ipnet,
95-
ldap: ldapPool,
107+
localPoolRange: ipnet,
108+
ldap: ldapPool,
109+
statuszServer: NewHijackedServer(nil),
110+
unavailableServer: NewUnavailableServer(),
96111
}
97112
for _, addr := range strings.Split(*httpAddrs, ",") {
98113
p.AddHTTPHostMatchRoute(addr, always, t)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"net"
6+
"net/http"
7+
_ "net/http/pprof"
8+
"os"
9+
)
10+
11+
func nolvsPresent() bool {
12+
if _, err := os.Stat("/etc/nolvs"); err == nil {
13+
return true
14+
}
15+
return false
16+
}
17+
18+
// HijackedServer is an HTTP server that serves from connections hijacked from another server instead of a listening socket.
19+
// (See net/http.Hijacker for the opposite direction.)
20+
// Users can call HandleConn to handle any request(s) waiting on that net.Conn.
21+
type HijackedServer struct {
22+
connCh chan net.Conn
23+
}
24+
25+
// NewHijackedServer constructs a HijackedServer that handles incoming HTTP connections with handler.
26+
func NewHijackedServer(handler http.Handler) *HijackedServer {
27+
s := &HijackedServer{
28+
connCh: make(chan net.Conn),
29+
}
30+
go http.Serve(s, handler)
31+
return s
32+
}
33+
34+
// Accept is called by http.Server to acquire a new connection.
35+
func (s *HijackedServer) Accept() (net.Conn, error) {
36+
c, ok := <-s.connCh
37+
if ok {
38+
return c, nil
39+
}
40+
return nil, errors.New("closed")
41+
}
42+
43+
// Close shuts down the server.
44+
func (s *HijackedServer) Close() error {
45+
close(s.connCh)
46+
return nil
47+
}
48+
49+
// Addr must be present to implement net.Listener
50+
func (s *HijackedServer) Addr() net.Addr {
51+
return nil
52+
}
53+
54+
// HandleConn instructs the server to take control of c and handle any HTTP request(s) that are waiting.
55+
func (s *HijackedServer) HandleConn(c net.Conn) {
56+
s.connCh <- c
57+
}
58+
59+
// NewUnavailableServer constructs a HijackedServer that serves 500 Service Unavailable for all requests.
60+
func NewUnavailableServer() *HijackedServer {
61+
return NewHijackedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
62+
http.Error(w, "0 proxy nolvs", http.StatusServiceUnavailable)
63+
}))
64+
}

0 commit comments

Comments
 (0)