route/cmd/routed/main.go

184 lines
3.7 KiB
Go
Raw Normal View History

2017-01-18 09:57:18 +00:00
package main
import (
2017-10-01 13:28:13 +00:00
"context"
2017-01-22 18:16:18 +00:00
"crypto/tls"
2017-01-18 09:57:18 +00:00
"flag"
"math/rand"
"net"
"net/http"
"os"
"os/signal"
2017-01-18 09:57:18 +00:00
"time"
2017-10-01 13:54:56 +00:00
_ "git.xeserv.us/xena/route/internal"
"git.xeserv.us/xena/route/internal/middleware"
"git.xeserv.us/xena/route/internal/routecrypto"
2017-04-28 23:28:03 +00:00
"github.com/Xe/ln"
"github.com/caarlos0/env"
2017-01-18 09:57:18 +00:00
"github.com/facebookgo/flagenv"
_ "github.com/joho/godotenv/autoload"
2017-12-12 02:51:45 +00:00
"github.com/lucas-clemente/quic-go/h2quic"
2017-01-18 09:57:18 +00:00
)
var (
2017-01-26 04:22:27 +00:00
sslCertKey = flag.String("ssl-cert-key", "", "if set encrypt SSL certs with this key")
2017-01-18 09:57:18 +00:00
)
func main() {
flag.Parse()
flagenv.Parse()
rand.Seed(time.Now().Unix())
2017-10-01 13:28:13 +00:00
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
2017-01-18 09:57:18 +00:00
certKey, err := routecrypto.ParseKey(*sslCertKey)
if err != nil {
ln.FatalErr(ctx, err, ln.Action("parse cert key"))
}
2017-01-26 04:22:27 +00:00
2017-12-15 18:18:13 +00:00
scfg := Config{}
err = env.Parse(&scfg)
2017-01-18 09:57:18 +00:00
if err != nil {
2017-10-01 13:28:13 +00:00
ln.FatalErr(ctx, err, ln.Action("parsing environment for config"))
2017-01-18 09:57:18 +00:00
}
2017-04-28 23:28:03 +00:00
scfg.CertKey = certKey
2017-01-18 09:57:18 +00:00
2017-12-15 18:18:13 +00:00
s, err := New(scfg)
2017-04-28 23:28:03 +00:00
if err != nil {
2017-10-01 13:28:13 +00:00
ln.FatalErr(ctx, err, ln.Action("create server instance"))
2017-01-22 18:16:18 +00:00
}
2018-01-20 17:40:54 +00:00
go setupQuic(ctx, s, scfg)
go setupTLS(ctx, s, scfg)
go setupHTTP(ctx, s, scfg)
ch := make(chan os.Signal, 2)
go func() {
val := <-ch
2017-04-28 23:28:03 +00:00
ln.Log(ctx, ln.F{"signal": val.String()}, ln.Action("signal recieved"))
cancel()
}()
signal.Notify(ch, os.Interrupt)
2018-01-20 17:30:47 +00:00
<-ctx.Done()
2018-01-20 17:40:54 +00:00
signal.Reset(os.Interrupt)
fmt.Printlf("%s is now waiting for final shutdown, press ^C again to kill it now\n", os.Args[0])
time.Sleep(30 * time.Second)
}
2018-01-20 17:40:54 +00:00
func setupHTTP(ctx context.Context, s *Server, scfg Config) {
f := ln.F{
"kind": "http",
"addr": scfg.WebAddr,
}
2017-10-01 13:28:13 +00:00
// listen on HTTP listener
2017-04-28 23:28:03 +00:00
l, err := net.Listen("tcp", scfg.WebAddr)
2017-01-18 09:57:18 +00:00
if err != nil {
2018-01-20 17:40:54 +00:00
ln.FatalErr(ctx, err, f, ln.Action("listening on HTTP port"))
2017-01-18 09:57:18 +00:00
}
defer l.Close()
hs := &http.Server{
2018-01-17 04:49:45 +00:00
Handler: s.Manager.HTTPHandler(http.HandlerFunc(insecureRedirect)),
Addr: scfg.WebAddr,
2017-01-18 09:57:18 +00:00
}
go ln.FatalErr(ctx, hs.Serve(l))
for {
select {
case <-ctx.Done():
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown signal recieved"))
hs.SetKeepAlivesEnabled(false)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
hs.Shutdown(ctx)
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown complete"))
return
}
}
2017-01-18 09:57:18 +00:00
}
2017-01-22 18:16:18 +00:00
2018-01-20 17:40:54 +00:00
func setupQuic(ctx context.Context, s *Server, scfg Config) {
f := ln.F{
"kind": "quic",
"addr": scfg.QuicAddr,
}
2017-12-12 02:51:45 +00:00
qs := &h2quic.Server{
Server: &http.Server{
Handler: middleware.Trace(s),
Addr: scfg.QuicAddr,
TLSConfig: &tls.Config{
GetCertificate: s.GetCertificate,
},
2018-01-20 16:59:16 +00:00
IdleTimeout: 5 * time.Minute,
ReadHeaderTimeout: time.Second,
2017-12-12 02:51:45 +00:00
},
}
2018-01-03 19:12:21 +00:00
s.QuicServer = qs
go ln.FatalErr(context.Background(), qs.ListenAndServe())
2017-12-12 02:51:45 +00:00
for {
select {
case <-ctx.Done():
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown signal recieved"))
qs.SetKeepAlivesEnabled(false)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
qs.Shutdown(ctx)
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown complete"))
return
}
2017-12-12 02:51:45 +00:00
}
}
2018-01-20 17:41:34 +00:00
func setupTLS(ctx context.Context, s *Server, scfg Config) {
2018-01-20 17:40:54 +00:00
f := ln.F{
"kind": "https",
"addr": scfg.SSLAddr,
}
2017-01-22 18:16:18 +00:00
hs := &http.Server{
2017-10-01 13:54:56 +00:00
Handler: middleware.Trace(s),
2017-04-28 23:28:03 +00:00
Addr: scfg.SSLAddr,
2017-01-22 18:16:18 +00:00
TLSConfig: &tls.Config{
2017-04-28 23:28:03 +00:00
GetCertificate: s.GetCertificate,
2017-01-22 18:16:18 +00:00
},
2018-01-20 16:59:16 +00:00
IdleTimeout: 5 * time.Minute,
ReadHeaderTimeout: time.Second,
2017-01-22 18:16:18 +00:00
}
go ln.FatalErr(context.Background(), hs.ListenAndServeTLS("", ""))
2017-10-01 13:28:13 +00:00
for {
select {
case <-ctx.Done():
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown signal recieved"))
hs.SetKeepAlivesEnabled(false)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
hs.Shutdown(ctx)
2018-01-20 17:40:54 +00:00
ln.Log(ctx, f, ln.Action("shutdown complete"))
return
}
2017-10-01 13:28:13 +00:00
}
2017-01-22 18:16:18 +00:00
}