2015-06-24 11:39:46 +00:00
|
|
|
// Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/tls"
|
|
|
|
"flag"
|
|
|
|
"log"
|
2015-06-28 00:52:01 +00:00
|
|
|
"net"
|
2015-06-24 11:39:46 +00:00
|
|
|
"path/filepath"
|
|
|
|
"time"
|
|
|
|
|
2015-07-20 11:25:08 +00:00
|
|
|
"github.com/juju/ratelimit"
|
2015-06-24 11:39:46 +00:00
|
|
|
"github.com/syncthing/relaysrv/protocol"
|
2015-06-28 00:52:01 +00:00
|
|
|
|
|
|
|
syncthingprotocol "github.com/syncthing/protocol"
|
2015-06-24 11:39:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2015-09-02 20:35:52 +00:00
|
|
|
listen string
|
|
|
|
debug bool
|
2015-06-24 11:39:46 +00:00
|
|
|
|
|
|
|
sessionAddress []byte
|
|
|
|
sessionPort uint16
|
|
|
|
|
|
|
|
networkTimeout time.Duration
|
|
|
|
pingInterval time.Duration
|
|
|
|
messageTimeout time.Duration
|
2015-07-20 11:25:08 +00:00
|
|
|
|
|
|
|
sessionLimitBps int
|
|
|
|
globalLimitBps int
|
|
|
|
sessionLimiter *ratelimit.Bucket
|
|
|
|
globalLimiter *ratelimit.Bucket
|
2015-08-20 10:59:44 +00:00
|
|
|
|
|
|
|
statusAddr string
|
2015-06-24 11:39:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var dir, extAddress string
|
|
|
|
|
2015-09-02 20:35:52 +00:00
|
|
|
flag.StringVar(&listen, "listen", ":22067", "Protocol listen address")
|
2015-06-24 11:39:46 +00:00
|
|
|
flag.StringVar(&dir, "keys", ".", "Directory where cert.pem and key.pem is stored")
|
|
|
|
flag.DurationVar(&networkTimeout, "network-timeout", 2*time.Minute, "Timeout for network operations")
|
|
|
|
flag.DurationVar(&pingInterval, "ping-interval", time.Minute, "How often pings are sent")
|
|
|
|
flag.DurationVar(&messageTimeout, "message-timeout", time.Minute, "Maximum amount of time we wait for relevant messages to arrive")
|
2015-07-20 11:25:08 +00:00
|
|
|
flag.IntVar(&sessionLimitBps, "per-session-rate", sessionLimitBps, "Per session rate limit, in bytes/s")
|
|
|
|
flag.IntVar(&globalLimitBps, "global-rate", globalLimitBps, "Global rate limit, in bytes/s")
|
|
|
|
flag.BoolVar(&debug, "debug", false, "Enable debug output")
|
2015-08-20 10:59:44 +00:00
|
|
|
flag.StringVar(&statusAddr, "status-srv", ":22070", "Listen address for status service (blank to disable)")
|
2015-07-20 11:25:08 +00:00
|
|
|
|
|
|
|
flag.Parse()
|
2015-06-24 11:39:46 +00:00
|
|
|
|
2015-06-28 00:52:01 +00:00
|
|
|
if extAddress == "" {
|
2015-09-02 20:35:52 +00:00
|
|
|
extAddress = listen
|
2015-06-28 00:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
addr, err := net.ResolveTCPAddr("tcp", extAddress)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
sessionAddress = addr.IP[:]
|
|
|
|
sessionPort = uint16(addr.Port)
|
|
|
|
|
2015-06-24 11:39:46 +00:00
|
|
|
certFile, keyFile := filepath.Join(dir, "cert.pem"), filepath.Join(dir, "key.pem")
|
|
|
|
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Failed to load X509 key pair:", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tlsCfg := &tls.Config{
|
|
|
|
Certificates: []tls.Certificate{cert},
|
|
|
|
NextProtos: []string{protocol.ProtocolName},
|
|
|
|
ClientAuth: tls.RequestClientCert,
|
|
|
|
SessionTicketsDisabled: true,
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
MinVersion: tls.VersionTLS12,
|
|
|
|
CipherSuites: []uint16{
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
|
|
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
|
|
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2015-06-28 00:52:01 +00:00
|
|
|
id := syncthingprotocol.NewDeviceID(cert.Certificate[0])
|
|
|
|
if debug {
|
|
|
|
log.Println("ID:", id)
|
|
|
|
}
|
2015-06-24 11:39:46 +00:00
|
|
|
|
2015-07-20 11:25:08 +00:00
|
|
|
if sessionLimitBps > 0 {
|
|
|
|
sessionLimiter = ratelimit.NewBucketWithRate(float64(sessionLimitBps), int64(2*sessionLimitBps))
|
|
|
|
}
|
|
|
|
if globalLimitBps > 0 {
|
|
|
|
globalLimiter = ratelimit.NewBucketWithRate(float64(globalLimitBps), int64(2*globalLimitBps))
|
|
|
|
}
|
|
|
|
|
2015-08-20 10:59:44 +00:00
|
|
|
if statusAddr != "" {
|
|
|
|
go statusService(statusAddr)
|
|
|
|
}
|
|
|
|
|
2015-09-02 20:35:52 +00:00
|
|
|
listener(listen, tlsCfg)
|
2015-06-24 11:39:46 +00:00
|
|
|
}
|