Changeset 691 in code
- Timestamp:
- Nov 15, 2021, 11:38:04 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/cmd/soju/main.go
r687 r691 38 38 } 39 39 40 func loadMOTD(srv *soju.Server, filename string) error {41 if filename == "" {42 return nil43 }44 45 b, err := ioutil.ReadFile(filename)46 if err != nil {47 return err48 }49 srv.SetMOTD(strings.TrimSuffix(string(b), "\n"))50 return nil51 }52 53 40 func bumpOpenedFileLimit() error { 54 41 var rlimit syscall.Rlimit … … 63 50 } 64 51 52 var ( 53 configPath string 54 debug bool 55 56 tlsCert atomic.Value // *tls.Certificate 57 ) 58 59 func loadConfig() (*config.Server, *soju.Config, error) { 60 var raw *config.Server 61 if configPath != "" { 62 var err error 63 raw, err = config.Load(configPath) 64 if err != nil { 65 return nil, nil, fmt.Errorf("failed to load config file: %v", err) 66 } 67 } else { 68 raw = config.Defaults() 69 } 70 71 var motd string 72 if raw.MOTDPath != "" { 73 b, err := ioutil.ReadFile(raw.MOTDPath) 74 if err != nil { 75 return nil, nil, fmt.Errorf("failed to load MOTD: %v", err) 76 } 77 motd = strings.TrimSuffix(string(b), "\n") 78 } 79 80 if raw.TLS != nil { 81 cert, err := tls.LoadX509KeyPair(raw.TLS.CertPath, raw.TLS.KeyPath) 82 if err != nil { 83 return nil, nil, fmt.Errorf("failed to load TLS certificate and key: %v", err) 84 } 85 tlsCert.Store(&cert) 86 } 87 88 cfg := &soju.Config{ 89 Hostname: raw.Hostname, 90 Title: raw.Title, 91 LogPath: raw.LogPath, 92 HTTPOrigins: raw.HTTPOrigins, 93 AcceptProxyIPs: raw.AcceptProxyIPs, 94 MaxUserNetworks: raw.MaxUserNetworks, 95 Debug: debug, 96 MOTD: motd, 97 } 98 return raw, cfg, nil 99 } 100 65 101 func main() { 66 102 var listen []string 67 var configPath string68 var debug bool69 103 flag.Var((*stringSliceFlag)(&listen), "listen", "listening address") 70 104 flag.StringVar(&configPath, "config", "", "path to configuration file") … … 72 106 flag.Parse() 73 107 74 var cfg *config.Server 75 if configPath != "" { 76 var err error 77 cfg, err = config.Load(configPath) 78 if err != nil { 79 log.Fatalf("failed to load config file: %v", err) 80 } 81 } else { 82 cfg = config.Defaults() 108 cfg, serverCfg, err := loadConfig() 109 if err != nil { 110 log.Fatal(err) 83 111 } 84 112 … … 98 126 99 127 var tlsCfg *tls.Config 100 var tlsCert atomic.Value101 128 if cfg.TLS != nil { 102 cert, err := tls.LoadX509KeyPair(cfg.TLS.CertPath, cfg.TLS.KeyPath)103 if err != nil {104 log.Fatalf("failed to load TLS certificate and key: %v", err)105 }106 tlsCert.Store(&cert)107 108 129 tlsCfg = &tls.Config{ 109 130 GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) { … … 114 135 115 136 srv := soju.NewServer(db) 116 srv.Hostname = cfg.Hostname 117 srv.Title = cfg.Title 118 srv.LogPath = cfg.LogPath 119 srv.HTTPOrigins = cfg.HTTPOrigins 120 srv.AcceptProxyIPs = cfg.AcceptProxyIPs 121 srv.MaxUserNetworks = cfg.MaxUserNetworks 122 srv.Debug = debug 123 124 if err := loadMOTD(srv, cfg.MOTDPath); err != nil { 125 log.Fatalf("failed to load MOTD: %v", err) 126 } 137 srv.SetConfig(serverCfg) 127 138 128 139 for _, listen := range cfg.Listen { … … 259 270 switch sig { 260 271 case syscall.SIGHUP: 261 log.Print("reloading TLS certificate and MOTD") 262 if cfg.TLS != nil { 263 cert, err := tls.LoadX509KeyPair(cfg.TLS.CertPath, cfg.TLS.KeyPath) 264 if err != nil { 265 log.Printf("failed to reload TLS certificate and key: %v", err) 266 break 267 } 268 tlsCert.Store(&cert) 269 } 270 if err := loadMOTD(srv, cfg.MOTDPath); err != nil { 271 log.Printf("failed to reload MOTD: %v", err) 272 log.Print("reloading configuration") 273 _, serverCfg, err := loadConfig() 274 if err != nil { 275 log.Printf("failed to reloading configuration: %v", err) 276 } else { 277 srv.SetConfig(serverCfg) 272 278 } 273 279 case syscall.SIGINT, syscall.SIGTERM: … … 287 293 return proxyproto.IGNORE, nil 288 294 } 289 if srv. AcceptProxyIPs.Contains(tcpAddr.IP) {295 if srv.Config().AcceptProxyIPs.Contains(tcpAddr.IP) { 290 296 return proxyproto.USE, nil 291 297 } -
trunk/conn.go
r594 r691 196 196 } 197 197 198 if c.srv. Debug {198 if c.srv.Config().Debug { 199 199 c.logger.Printf("sent: %v", msg) 200 200 } … … 249 249 } 250 250 251 if c.srv. Debug {251 if c.srv.Config().Debug { 252 252 c.logger.Printf("received: %v", msg) 253 253 } -
trunk/doc/soju.1.scd
r662 r691 45 45 be done by adding a "@<client>" suffix to the username. 46 46 47 soju will reload the TLS certificate/key and the MOTD file when it receives the 48 HUP signal. 47 soju will reload the configuration file, the TLS certificate/key and the MOTD 48 file when it receives the HUP signal. The configuration options _listen_, _db_ 49 and _log_ cannot be reloaded. 49 50 50 51 Administrators can broadcast a message to all bouncer users via _/notice -
trunk/downstream.go
r690 r691 291 291 dc.supportedCaps[k] = v 292 292 } 293 if srv.LogPath != "" { 293 // TODO: this is racy, we should only enable chathistory after 294 // authentication and then check that user.msgStore implements 295 // chatHistoryMessageStore 296 if srv.Config().LogPath != "" { 294 297 dc.supportedCaps["draft/chathistory"] = "" 295 298 } … … 997 1000 } 998 1001 999 if dc.srv.LogPath != ""&& dc.network != nil {1002 if _, ok := dc.user.msgStore.(chatHistoryMessageStore); ok && dc.network != nil { 1000 1003 dc.setSupportedCap("draft/event-playback", "") 1001 1004 } else { … … 1176 1179 isupport = append(isupport, fmt.Sprintf("BOUNCER_NETID=%v", dc.network.ID)) 1177 1180 } 1178 if dc.network == nil && dc.srv.Title != "" {1179 isupport = append(isupport, "NETWORK="+encodeISUPPORT( dc.srv.Title))1181 if title := dc.srv.Config().Title; dc.network == nil && title != "" { 1182 isupport = append(isupport, "NETWORK="+encodeISUPPORT(title)) 1180 1183 } 1181 1184 if dc.network == nil && dc.caps["soju.im/bouncer-networks"] { … … 1205 1208 Prefix: dc.srv.prefix(), 1206 1209 Command: irc.RPL_YOURHOST, 1207 Params: []string{dc.nick, "Your host is " + dc.srv. Hostname},1210 Params: []string{dc.nick, "Your host is " + dc.srv.Config().Hostname}, 1208 1211 }) 1209 1212 dc.SendMessage(&irc.Message{ 1210 1213 Prefix: dc.srv.prefix(), 1211 1214 Command: irc.RPL_MYINFO, 1212 Params: []string{dc.nick, dc.srv. Hostname, "soju", "aiwroO", "OovaimnqpsrtklbeI"},1215 Params: []string{dc.nick, dc.srv.Config().Hostname, "soju", "aiwroO", "OovaimnqpsrtklbeI"}, 1213 1216 }) 1214 1217 for _, msg := range generateIsupport(dc.srv.prefix(), dc.nick, isupport) { … … 1230 1233 } 1231 1234 1232 if motd := dc.user.srv. MOTD(); motd != "" && dc.network == nil {1235 if motd := dc.user.srv.Config().MOTD; motd != "" && dc.network == nil { 1233 1236 for _, msg := range generateMOTD(dc.srv.prefix(), dc.nick, motd) { 1234 1237 dc.SendMessage(msg) … … 1421 1424 destination = msg.Params[1] 1422 1425 } 1423 if destination != "" && destination != dc.srv.Hostname { 1426 hostname := dc.srv.Config().Hostname 1427 if destination != "" && destination != hostname { 1424 1428 return ircError{&irc.Message{ 1425 1429 Command: irc.ERR_NOSUCHSERVER, … … 1430 1434 Prefix: dc.srv.prefix(), 1431 1435 Command: "PONG", 1432 Params: []string{ dc.srv.Hostname, source},1436 Params: []string{hostname, source}, 1433 1437 }) 1434 1438 return nil … … 1947 1951 Username: dc.user.Username, 1948 1952 Hostname: dc.hostname, 1949 Server: dc.srv. Hostname,1953 Server: dc.srv.Config().Hostname, 1950 1954 Nickname: dc.nick, 1951 1955 Flags: flags, … … 1966 1970 Username: servicePrefix.User, 1967 1971 Hostname: servicePrefix.Host, 1968 Server: dc.srv. Hostname,1972 Server: dc.srv.Config().Hostname, 1969 1973 Nickname: serviceNick, 1970 1974 Flags: "H*", … … 2026 2030 Prefix: dc.srv.prefix(), 2027 2031 Command: irc.RPL_WHOISSERVER, 2028 Params: []string{dc.nick, dc.nick, dc.srv. Hostname, "soju"},2032 Params: []string{dc.nick, dc.nick, dc.srv.Config().Hostname, "soju"}, 2029 2033 }) 2030 2034 if dc.user.Admin { … … 2056 2060 Prefix: dc.srv.prefix(), 2057 2061 Command: irc.RPL_WHOISSERVER, 2058 Params: []string{dc.nick, serviceNick, dc.srv. Hostname, "soju"},2062 Params: []string{dc.nick, serviceNick, dc.srv.Config().Hostname, "soju"}, 2059 2063 }) 2060 2064 dc.SendMessage(&irc.Message{ … … 2105 2109 2106 2110 for _, name := range strings.Split(targetsStr, ",") { 2107 if name == "$"+dc.srv. Hostname || (name == "$*" && dc.network == nil) {2111 if name == "$"+dc.srv.Config().Hostname || (name == "$*" && dc.network == nil) { 2108 2112 // "$" means a server mask follows. If it's the bouncer's 2109 2113 // hostname, broadcast the message to all bouncer users. -
trunk/server.go
r689 r691 54 54 } 55 55 56 type Serverstruct {56 type Config struct { 57 57 Hostname string 58 58 Title string 59 Logger Logger60 59 LogPath string 61 60 Debug bool … … 63 62 AcceptProxyIPs config.IPSet 64 63 MaxUserNetworks int 65 Identd *Identd // can be nil 66 64 MOTD string 65 } 66 67 type Server struct { 68 Logger Logger 69 Identd *Identd // can be nil 70 71 config atomic.Value // *Config 67 72 db Database 68 73 stopWG sync.WaitGroup … … 72 77 listeners map[net.Listener]struct{} 73 78 users map[string]*user 74 75 motd atomic.Value // string76 79 } 77 80 78 81 func NewServer(db Database) *Server { 79 82 srv := &Server{ 80 Logger: log.New(log.Writer(), "", log.LstdFlags), 81 MaxUserNetworks: -1, 82 db: db, 83 listeners: make(map[net.Listener]struct{}), 84 users: make(map[string]*user), 85 } 86 srv.motd.Store("") 83 Logger: log.New(log.Writer(), "", log.LstdFlags), 84 db: db, 85 listeners: make(map[net.Listener]struct{}), 86 users: make(map[string]*user), 87 } 88 srv.config.Store(&Config{Hostname: "localhost", MaxUserNetworks: -1}) 87 89 return srv 88 90 } 89 91 90 92 func (s *Server) prefix() *irc.Prefix { 91 return &irc.Prefix{Name: s.Hostname} 93 return &irc.Prefix{Name: s.Config().Hostname} 94 } 95 96 func (s *Server) Config() *Config { 97 return s.config.Load().(*Config) 98 } 99 100 func (s *Server) SetConfig(cfg *Config) { 101 s.config.Store(cfg) 92 102 } 93 103 … … 240 250 conn, err := websocket.Accept(w, req, &websocket.AcceptOptions{ 241 251 Subprotocols: []string{"text.ircv3.net"}, // non-compliant, fight me 242 OriginPatterns: s. HTTPOrigins,252 OriginPatterns: s.Config().HTTPOrigins, 243 253 }) 244 254 if err != nil { … … 250 260 if host, _, err := net.SplitHostPort(req.RemoteAddr); err == nil { 251 261 if ip := net.ParseIP(host); ip != nil { 252 isProxy = s. AcceptProxyIPs.Contains(ip)262 isProxy = s.Config().AcceptProxyIPs.Contains(ip) 253 263 } 254 264 } … … 294 304 return &stats 295 305 } 296 297 func (s *Server) SetMOTD(motd string) {298 s.motd.Store(motd)299 }300 301 func (s *Server) MOTD() string {302 return s.motd.Load().(string)303 } -
trunk/service.go
r680 r691 1051 1051 Prefix: servicePrefix, 1052 1052 Command: "NOTICE", 1053 Params: []string{"$" + dc.srv. Hostname, text},1053 Params: []string{"$" + dc.srv.Config().Hostname, text}, 1054 1054 } 1055 1055 var err error -
trunk/user.go
r684 r691 416 416 417 417 var msgStore messageStore 418 if srv.LogPath != "" {419 msgStore = newFSMessageStore( srv.LogPath, record.Username)418 if logPath := srv.Config().LogPath; logPath != "" { 419 msgStore = newFSMessageStore(logPath, record.Username) 420 420 } else { 421 421 msgStore = newMemoryMessageStore() … … 777 777 } 778 778 779 if u.srv.MaxUserNetworks >= 0 && len(u.networks) >= u.srv.MaxUserNetworks{779 if max := u.srv.Config().MaxUserNetworks; max >= 0 && len(u.networks) >= max { 780 780 return nil, fmt.Errorf("maximum number of networks reached") 781 781 }
Note:
See TracChangeset
for help on using the changeset viewer.