Changeset 317 in code for trunk


Ignore:
Timestamp:
Jun 4, 2020, 6:16:23 PM (5 years ago)
Author:
contact
Message:

Allow multiple listeners, default to ircs

Users can now specify multiple "listen" directives in their
configuration file. If -listen is specified on the CLI, it's added to
the list of listeners.

Listeners are now parsed as URLs. If the scheme is missing "ircs" is
assumed. URLs allow to enable/disable TLS on a per-listener basis and
will be used for Unix sockets too.

The default listening address is changed from irc+insecure://:6667 to
ircs://:6697. This avoids setting up an insecure listener opened to
everybody.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/README.md

    r290 r317  
    1414
    1515    go run ./cmd/sojuctl create-user <username>
    16     go run ./cmd/soju
     16    go run ./cmd/soju -listen irc+insecure://127.0.0.1:6667
    1717
    1818Then connect with username `<username>/chat.freenode.net` and join `#soju`.
  • trunk/cmd/soju/main.go

    r178 r317  
    66        "log"
    77        "net"
     8        "net/url"
     9        "strings"
    810
    911        "git.sr.ht/~emersion/soju"
     
    1214
    1315func main() {
    14         var addr, configPath string
     16        var listen, configPath string
    1517        var debug bool
    16         flag.StringVar(&addr, "listen", "", "listening address")
     18        flag.StringVar(&listen, "listen", "", "listening address")
    1719        flag.StringVar(&configPath, "config", "", "path to configuration file")
    1820        flag.BoolVar(&debug, "debug", false, "enable debug logging")
     
    3032        }
    3133
    32         if addr != "" {
    33                 cfg.Addr = addr
     34        if listen != "" {
     35                cfg.Listen = append(cfg.Listen, listen)
     36        }
     37        if len(cfg.Listen) == 0 {
     38                cfg.Listen = []string{":6697"}
    3439        }
    3540
     
    3944        }
    4045
    41         var ln net.Listener
     46        var tlsCfg *tls.Config
    4247        if cfg.TLS != nil {
    4348                cert, err := tls.LoadX509KeyPair(cfg.TLS.CertPath, cfg.TLS.KeyPath)
     
    4550                        log.Fatalf("failed to load TLS certificate and key: %v", err)
    4651                }
    47 
    48                 tlsCfg := &tls.Config{Certificates: []tls.Certificate{cert}}
    49                 ln, err = tls.Listen("tcp", cfg.Addr, tlsCfg)
    50                 if err != nil {
    51                         log.Fatalf("failed to start TLS listener: %v", err)
    52                 }
    53         } else {
    54                 var err error
    55                 ln, err = net.Listen("tcp", cfg.Addr)
    56                 if err != nil {
    57                         log.Fatalf("failed to start listener: %v", err)
    58                 }
     52                tlsCfg = &tls.Config{Certificates: []tls.Certificate{cert}}
    5953        }
    6054
     
    6559        srv.Debug = debug
    6660
    67         log.Printf("server listening on %q", cfg.Addr)
    68         go func() {
    69                 if err := srv.Run(); err != nil {
    70                         log.Fatal(err)
     61        for _, listen := range cfg.Listen {
     62                listenURI := listen
     63                if !strings.Contains(listenURI, ":/") {
     64                        // This is a raw domain name, make it an URL with an empty scheme
     65                        listenURI = "//" + listenURI
    7166                }
    72         }()
    73         log.Fatal(srv.Serve(ln))
     67                u, err := url.Parse(listenURI)
     68                if err != nil {
     69                        log.Fatalf("failed to parse listen URI %q: %v", listen, err)
     70                }
     71
     72                switch u.Scheme {
     73                case "ircs", "":
     74                        if tlsCfg == nil {
     75                                log.Fatalf("failed to listen on %q: missing TLS configuration", listen)
     76                        }
     77                        host := u.Host
     78                        if _, _, err := net.SplitHostPort(host); err != nil {
     79                                host = host + ":6697"
     80                        }
     81                        ln, err := tls.Listen("tcp", host, tlsCfg)
     82                        if err != nil {
     83                                log.Fatalf("failed to start TLS listener on %q: %v", listen, err)
     84                        }
     85                        go func() {
     86                                log.Fatal(srv.Serve(ln))
     87                        }()
     88                case "irc+insecure":
     89                        host := u.Host
     90                        if _, _, err := net.SplitHostPort(host); err != nil {
     91                                host = host + ":6667"
     92                        }
     93                        ln, err := net.Listen("tcp", host)
     94                        if err != nil {
     95                                log.Fatalf("failed to start listener on %q: %v", listen, err)
     96                        }
     97                        go func() {
     98                                log.Fatal(srv.Serve(ln))
     99                        }()
     100                default:
     101                        log.Fatalf("failed to listen on %q: unsupported scheme", listen)
     102                }
     103
     104                log.Printf("server listening on %q", listen)
     105        }
     106        log.Fatal(srv.Run())
    74107}
  • trunk/config/config.go

    r200 r317  
    1515
    1616type Server struct {
    17         Addr      string
     17        Listen    []string
    1818        Hostname  string
    1919        TLS       *TLS
     
    2929        }
    3030        return &Server{
    31                 Addr:      ":6667",
    3231                Hostname:  hostname,
    3332                SQLDriver: "sqlite3",
     
    6968                switch d.Name {
    7069                case "listen":
    71                         if err := d.parseParams(&srv.Addr); err != nil {
     70                        var uri string
     71                        if err := d.parseParams(&uri); err != nil {
    7272                                return nil, err
    7373                        }
     74                        srv.Listen = append(srv.Listen, uri)
    7475                case "hostname":
    7576                        if err := d.parseParams(&srv.Hostname); err != nil {
  • trunk/doc/soju.1.scd

    r307 r317  
    5757        passwords).
    5858
    59 *-listen* <address>
    60         Listening address (default: ":6667").
     59*-listen* <uri>
     60        Listening URI (default: ":6697").
    6161
    6262# CONFIG FILE
     
    6464The config file has one directive per line.
    6565
    66 *listen* <address>
    67         Listening address (default: ":6667").
     66*listen* <uri>
     67        Listening URI (default: ":6697").
     68
     69        The following URIs are supported:
     70
     71        - _[ircs://][host][:port]_ listens with TLS over TCP (default port if
     72          omitted: 6697)
     73        - _irc+insecure://[host][:port]_ listens with plain-text over TCP (default
     74          port if omitted: 6667)
     75
     76        If the scheme is omitted, "ircs" is assumed. If multiple *listen*
     77        directives are specified, soju will listen on each of them.
    6878
    6979*hostname* <name>
     
    98108
    99109        _addr_ supports several connection types:
     110
    100111        - _[ircs://]host[:port]_ connects with TLS over TCP
    101112        - _irc+insecure://host[:port]_ connects with plain-text TCP
Note: See TracChangeset for help on using the changeset viewer.