blob: 903db8b7e2c9cc85c85958b01571d56151bac6a0 [file] [log] [blame]
// proxyd is a daemon that listens for connections from veyron services
// (typically behind NATs) and proxies these services to the outside world.
package main
import (
"flag"
"net/http"
_ "net/http/pprof"
"time"
"veyron.io/veyron/veyron/runtimes/google/ipc/stream/proxy"
"veyron.io/veyron/veyron/runtimes/google/lib/publisher"
"veyron.io/veyron/veyron2/naming"
"veyron.io/veyron/veyron2/rt"
"veyron.io/veyron/veyron2/vlog"
)
var (
// TODO(rthellend): Remove the protocol and address flags when the config
// manager is working.
protocol = flag.String("protocol", "tcp", "protocol to listen on")
address = flag.String("address", ":0", "address to listen on")
pubAddress = flag.String("published_address", "", "Network address the proxy publishes. If empty, the value of --address will be used")
httpAddr = flag.String("http", ":14142", "Network address on which the HTTP debug server runs")
healthzAddr = flag.String("healthz_address", "", "Network address on which the HTTP healthz server runs. It is intended to be used with a load balancer. The load balancer must be able to reach this address in order to verify that the proxy server is running")
name = flag.String("name", "", "Name to mount the proxy as")
)
func main() {
r := rt.Init()
defer r.Cleanup()
rid, err := naming.NewRoutingID()
if err != nil {
vlog.Fatal(err)
}
proxy, err := proxy.New(rid, nil, *protocol, *address, *pubAddress)
if err != nil {
vlog.Fatal(err)
}
defer proxy.Shutdown()
if len(*name) > 0 {
publisher := publisher.New(r.NewContext(), r.Namespace(), time.Minute)
defer publisher.WaitForStop()
defer publisher.Stop()
publisher.AddServer(naming.JoinAddressName(proxy.Endpoint().String(), "//"), false)
publisher.AddName(*name)
}
if len(*healthzAddr) != 0 {
go startHealthzServer(*healthzAddr)
}
http.Handle("/", proxy)
if err = http.ListenAndServe(*httpAddr, nil); err != nil {
vlog.Fatal(err)
}
}
// healthzHandler implements net/http.Handler
type healthzHandler struct{}
func (healthzHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}
// startHealthzServer starts a HTTP server that simply returns "ok" to every
// request. This is needed to let the load balancer know that the proxy server
// is running.
func startHealthzServer(addr string) {
s := http.Server{
Addr: addr,
Handler: healthzHandler{},
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
}
if err := s.ListenAndServe(); err != nil {
vlog.Fatal(err)
}
}