From 19795a23216334b835bae59c123a683c825f59c6 Mon Sep 17 00:00:00 2001 From: delthas Date: Mon, 27 Apr 2020 18:02:33 +0200 Subject: [PATCH] Add support for IRC address schemes This is preparatory work for adding other connection types to upstream servers. The service command `network create` now accepts a scheme in the address flag, which specifies how to connect to the upstream server. The only supported scheme for now is ircs, which is also the default if no scheme is specified. ircs connects to a network over a TLS TCP connection. --- doc/soju.1.scd | 7 ++++++- service.go | 9 +++++++++ upstream.go | 28 +++++++++++++++++++++++----- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/doc/soju.1.scd b/doc/soju.1.scd index 67705e3..411266f 100644 --- a/doc/soju.1.scd +++ b/doc/soju.1.scd @@ -93,7 +93,12 @@ abbreviated form, for instance *network* can be abbreviated as *net* or just the command. *network create* *-addr* [options...] - Connect to a new network at _addr_. _-addr_ is mandatory. Other options are: + Connect to a new network at _addr_. _-addr_ is mandatory. + + _addr_ supports several connection types: + - _[ircs://]host[:port]_ connects with TLS over TCP + + Other options are: *-name* Short network name. This will be used instead of _addr_ to refer to the diff --git a/service.go b/service.go index ecbd6aa..6df9fa9 100644 --- a/service.go +++ b/service.go @@ -203,6 +203,15 @@ func handleServiceCreateNetwork(dc *downstreamConn, params []string) error { return fmt.Errorf("flag -addr is required") } + if addrParts := strings.SplitN(*addr, "://", 2); len(addrParts) == 2 { + scheme := addrParts[0] + switch scheme { + case "ircs": + default: + return fmt.Errorf("unknown scheme %q (supported schemes: ircs)", scheme) + } + } + for _, command := range connectCommands { _, err := irc.ParseMessage(command) if err != nil { diff --git a/upstream.go b/upstream.go index 98a05c2..97c77fa 100644 --- a/upstream.go +++ b/upstream.go @@ -66,15 +66,33 @@ type upstreamConn struct { func connectToUpstream(network *network) (*upstreamConn, error) { logger := &prefixLogger{network.user.srv.Logger, fmt.Sprintf("upstream %q: ", network.Addr)} - addr := network.Addr - if !strings.ContainsRune(addr, ':') { - addr = addr + ":6697" + var scheme string + var addr string + + addrParts := strings.SplitN(network.Addr, "://", 2) + if len(addrParts) == 2 { + scheme = addrParts[0] + addr = addrParts[1] + } else { + scheme = "ircs" + addr = addrParts[0] } dialer := net.Dialer{Timeout: connectTimeout} - logger.Printf("connecting to TLS server at address %q", addr) - netConn, err := tls.DialWithDialer(&dialer, "tcp", addr, nil) + var netConn net.Conn + var err error + switch scheme { + case "ircs": + if !strings.ContainsRune(addr, ':') { + addr = addr + ":6697" + } + + logger.Printf("connecting to TLS server at address %q", addr) + netConn, err = tls.DialWithDialer(&dialer, "tcp", addr, nil) + default: + return nil, fmt.Errorf("failed to dial %q: unknown scheme: %v", addr, scheme) + } if err != nil { return nil, fmt.Errorf("failed to dial %q: %v", addr, err) }