Skip to content

Commit 7e4e4d4

Browse files
committed
Add a special vhost for health checking that uses /etc/nolvs
Also adds another special vhost for debugging/monitoring
1 parent d61706d commit 7e4e4d4

File tree

2 files changed

+82
-4
lines changed

2 files changed

+82
-4
lines changed

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

Lines changed: 19 additions & 4 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)
@@ -90,8 +103,10 @@ func main() {
90103

91104
var p tcpproxy.Proxy
92105
t := &ldapTarget{
93-
localPoolRange: ipnet,
94-
ldap: ldapPool,
106+
localPoolRange: ipnet,
107+
ldap: ldapPool,
108+
statuszServer: NewHijackedServer(nil),
109+
unavailableServer: NewUnavailableServer(),
95110
}
96111
for _, addr := range strings.Split(*httpAddrs, ",") {
97112
p.AddHTTPHostMatchRoute(addr, always, t)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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 hijacked connections instead of a listening socket.
19+
// Users can call HandleConn to handle any request(s) waiting on that net.Conn.
20+
type HijackedServer struct {
21+
connCh chan net.Conn
22+
}
23+
24+
// NewHijackedServer constructs a HijackedServer that handles incoming HTTP connections with handler.
25+
func NewHijackedServer(handler http.Handler) *HijackedServer {
26+
s := &HijackedServer{
27+
connCh: make(chan net.Conn),
28+
}
29+
go http.Serve(s, handler)
30+
return s
31+
}
32+
33+
// Accept is called by http.Server to acquire a new connection.
34+
func (s *HijackedServer) Accept() (net.Conn, error) {
35+
c, ok := <-s.connCh
36+
if ok {
37+
return c, nil
38+
}
39+
return nil, errors.New("closed")
40+
}
41+
42+
// Close shuts down the server.
43+
func (s *HijackedServer) Close() error {
44+
close(s.connCh)
45+
return nil
46+
}
47+
48+
// Addr must be present to implement net.Listener
49+
func (s *HijackedServer) Addr() net.Addr {
50+
return nil
51+
}
52+
53+
// HandleConn instructs the server to take control of c and handle any HTTP request(s) that are waiting.
54+
func (s *HijackedServer) HandleConn(c net.Conn) {
55+
s.connCh <- c
56+
}
57+
58+
// NewUnavailableServer constructs a HijackedServer that serves 500 Service Unavailable for all requests.
59+
func NewUnavailableServer() *HijackedServer {
60+
return NewHijackedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
61+
http.Error(w, "0 proxy nolvs", http.StatusServiceUnavailable)
62+
}))
63+
}

0 commit comments

Comments
 (0)