|
@@ -21,7 +21,6 @@ import (
|
21
|
21
|
"time"
|
22
|
22
|
|
23
|
23
|
"github.com/goshuirc/irc-go/ircfmt"
|
24
|
|
- "github.com/goshuirc/irc-go/ircmsg"
|
25
|
24
|
"github.com/oragono/oragono/irc/caps"
|
26
|
25
|
"github.com/oragono/oragono/irc/connection_limits"
|
27
|
26
|
"github.com/oragono/oragono/irc/isupport"
|
|
@@ -35,10 +34,7 @@ import (
|
35
|
34
|
|
36
|
35
|
var (
|
37
|
36
|
// common error line to sub values into
|
38
|
|
- errorMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "%s ")}[0]).Line()
|
39
|
|
-
|
40
|
|
- // common error responses
|
41
|
|
- couldNotParseIPMsg, _ = (&[]ircmsg.IrcMessage{ircmsg.MakeMessage(nil, "", "ERROR", "Unable to parse your IP address")}[0]).Line()
|
|
37
|
+ errorMsg = "ERROR :%s\r\n"
|
42
|
38
|
|
43
|
39
|
// supportedUserModesString acts as a cache for when we introduce users
|
44
|
40
|
supportedUserModesString = modes.SupportedUserModes.String()
|
|
@@ -58,6 +54,7 @@ var (
|
58
|
54
|
type ListenerWrapper struct {
|
59
|
55
|
listener net.Listener
|
60
|
56
|
tlsConfig *tls.Config
|
|
57
|
+ isTor bool
|
61
|
58
|
shouldStop bool
|
62
|
59
|
// protects atomic update of tlsConfig and shouldStop:
|
63
|
60
|
configMutex sync.Mutex // tier 1
|
|
@@ -92,6 +89,7 @@ type Server struct {
|
92
|
89
|
signals chan os.Signal
|
93
|
90
|
snomasks *SnoManager
|
94
|
91
|
store *buntdb.DB
|
|
92
|
+ torLimiter connection_limits.TorLimiter
|
95
|
93
|
whoWas *WhoWasList
|
96
|
94
|
stats *Stats
|
97
|
95
|
semaphores *ServerSemaphores
|
|
@@ -109,6 +107,7 @@ var (
|
109
|
107
|
type clientConn struct {
|
110
|
108
|
Conn net.Conn
|
111
|
109
|
IsTLS bool
|
|
110
|
+ IsTor bool
|
112
|
111
|
}
|
113
|
112
|
|
114
|
113
|
// NewServer returns a new Oragono server.
|
|
@@ -252,22 +251,27 @@ func (server *Server) Run() {
|
252
|
251
|
}
|
253
|
252
|
|
254
|
253
|
func (server *Server) acceptClient(conn clientConn) {
|
255
|
|
- // check IP address
|
256
|
|
- ipaddr := utils.AddrToIP(conn.Conn.RemoteAddr())
|
257
|
|
- if ipaddr != nil {
|
258
|
|
- isBanned, banMsg := server.checkBans(ipaddr)
|
259
|
|
- if isBanned {
|
260
|
|
- // this might not show up properly on some clients, but our objective here is just to close the connection out before it has a load impact on us
|
261
|
|
- conn.Conn.Write([]byte(fmt.Sprintf(errorMsg, banMsg)))
|
262
|
|
- conn.Conn.Close()
|
263
|
|
- return
|
264
|
|
- }
|
|
254
|
+ var isBanned bool
|
|
255
|
+ var banMsg string
|
|
256
|
+ var ipaddr net.IP
|
|
257
|
+ if conn.IsTor {
|
|
258
|
+ ipaddr = utils.IPv4LoopbackAddress
|
|
259
|
+ isBanned, banMsg = server.checkTorLimits()
|
|
260
|
+ } else {
|
|
261
|
+ ipaddr = utils.AddrToIP(conn.Conn.RemoteAddr())
|
|
262
|
+ isBanned, banMsg = server.checkBans(ipaddr)
|
|
263
|
+ }
|
|
264
|
+
|
|
265
|
+ if isBanned {
|
|
266
|
+ // this might not show up properly on some clients, but our objective here is just to close the connection out before it has a load impact on us
|
|
267
|
+ conn.Conn.Write([]byte(fmt.Sprintf(errorMsg, banMsg)))
|
|
268
|
+ conn.Conn.Close()
|
|
269
|
+ return
|
265
|
270
|
}
|
266
|
271
|
|
267
|
272
|
server.logger.Info("localconnect-ip", fmt.Sprintf("Client connecting from %v", ipaddr))
|
268
|
|
- // prolly don't need to alert snomasks on this, only on connection reg
|
269
|
273
|
|
270
|
|
- NewClient(server, conn.Conn, conn.IsTLS)
|
|
274
|
+ go RunNewClient(server, conn)
|
271
|
275
|
}
|
272
|
276
|
|
273
|
277
|
func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
|
|
@@ -310,12 +314,23 @@ func (server *Server) checkBans(ipaddr net.IP) (banned bool, message string) {
|
310
|
314
|
return false, ""
|
311
|
315
|
}
|
312
|
316
|
|
|
317
|
+func (server *Server) checkTorLimits() (banned bool, message string) {
|
|
318
|
+ switch server.torLimiter.AddClient() {
|
|
319
|
+ case connection_limits.ErrLimitExceeded:
|
|
320
|
+ return true, "Too many clients from the Tor network"
|
|
321
|
+ case connection_limits.ErrThrottleExceeded:
|
|
322
|
+ return true, "Exceeded connection throttle for the Tor network"
|
|
323
|
+ default:
|
|
324
|
+ return false, ""
|
|
325
|
+ }
|
|
326
|
+}
|
|
327
|
+
|
313
|
328
|
//
|
314
|
329
|
// IRC protocol listeners
|
315
|
330
|
//
|
316
|
331
|
|
317
|
332
|
// createListener starts a given listener.
|
318
|
|
-func (server *Server) createListener(addr string, tlsConfig *tls.Config, bindMode os.FileMode) (*ListenerWrapper, error) {
|
|
333
|
+func (server *Server) createListener(addr string, tlsConfig *tls.Config, isTor bool, bindMode os.FileMode) (*ListenerWrapper, error) {
|
319
|
334
|
// make listener
|
320
|
335
|
var listener net.Listener
|
321
|
336
|
var err error
|
|
@@ -338,6 +353,7 @@ func (server *Server) createListener(addr string, tlsConfig *tls.Config, bindMod
|
338
|
353
|
wrapper := ListenerWrapper{
|
339
|
354
|
listener: listener,
|
340
|
355
|
tlsConfig: tlsConfig,
|
|
356
|
+ isTor: isTor,
|
341
|
357
|
shouldStop: false,
|
342
|
358
|
}
|
343
|
359
|
|
|
@@ -349,10 +365,10 @@ func (server *Server) createListener(addr string, tlsConfig *tls.Config, bindMod
|
349
|
365
|
conn, err := listener.Accept()
|
350
|
366
|
|
351
|
367
|
// synchronously access config data:
|
352
|
|
- // whether TLS is enabled and whether we should stop listening
|
353
|
368
|
wrapper.configMutex.Lock()
|
354
|
369
|
shouldStop = wrapper.shouldStop
|
355
|
370
|
tlsConfig = wrapper.tlsConfig
|
|
371
|
+ isTor = wrapper.isTor
|
356
|
372
|
wrapper.configMutex.Unlock()
|
357
|
373
|
|
358
|
374
|
if err == nil {
|
|
@@ -362,6 +378,7 @@ func (server *Server) createListener(addr string, tlsConfig *tls.Config, bindMod
|
362
|
378
|
newConn := clientConn{
|
363
|
379
|
Conn: conn,
|
364
|
380
|
IsTLS: tlsConfig != nil,
|
|
381
|
+ IsTor: isTor,
|
365
|
382
|
}
|
366
|
383
|
// hand off the connection
|
367
|
384
|
go server.acceptClient(newConn)
|
|
@@ -524,7 +541,7 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
|
524
|
541
|
rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, cnick, tnick, tOper.WhoisLine)
|
525
|
542
|
}
|
526
|
543
|
if client.HasMode(modes.Operator) || client == target {
|
527
|
|
- rb.Add(nil, client.server.name, RPL_WHOISACTUALLY, cnick, tnick, fmt.Sprintf("%s@%s", target.username, utils.LookupHostname(target.IPString())), target.IPString(), client.t("Actual user@host, Actual IP"))
|
|
544
|
+ rb.Add(nil, client.server.name, RPL_WHOISACTUALLY, cnick, tnick, fmt.Sprintf("%s@%s", targetInfo.username, target.RawHostname()), target.IPString(), client.t("Actual user@host, Actual IP"))
|
528
|
545
|
}
|
529
|
546
|
if target.HasMode(modes.TLS) {
|
530
|
547
|
rb.Add(nil, client.server.name, RPL_WHOISSECURE, cnick, tnick, client.t("is using a secure connection"))
|
|
@@ -639,6 +656,9 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
639
|
656
|
return err
|
640
|
657
|
}
|
641
|
658
|
|
|
659
|
+ tlConf := &config.Server.TorListeners
|
|
660
|
+ server.torLimiter.Configure(tlConf.MaxConnections, tlConf.ThrottleDuration, tlConf.MaxConnectionsPerDuration)
|
|
661
|
+
|
642
|
662
|
// reload logging config
|
643
|
663
|
wasLoggingRawIO := !initial && server.logger.IsLoggingRawIO()
|
644
|
664
|
err = server.logger.ApplyConfig(config.Logging)
|
|
@@ -931,9 +951,9 @@ func (server *Server) loadDatastore(config *Config) error {
|
931
|
951
|
}
|
932
|
952
|
|
933
|
953
|
func (server *Server) setupListeners(config *Config) (err error) {
|
934
|
|
- logListener := func(addr string, tlsconfig *tls.Config) {
|
|
954
|
+ logListener := func(addr string, tlsconfig *tls.Config, isTor bool) {
|
935
|
955
|
server.logger.Info("listeners",
|
936
|
|
- fmt.Sprintf("now listening on %s, tls=%t.", addr, (tlsconfig != nil)),
|
|
956
|
+ fmt.Sprintf("now listening on %s, tls=%t, tor=%t.", addr, (tlsconfig != nil), isTor),
|
937
|
957
|
)
|
938
|
958
|
}
|
939
|
959
|
|
|
@@ -943,6 +963,15 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
943
|
963
|
return
|
944
|
964
|
}
|
945
|
965
|
|
|
966
|
+ isTorListener := func(listener string) bool {
|
|
967
|
+ for _, torListener := range config.Server.TorListeners.Listeners {
|
|
968
|
+ if listener == torListener {
|
|
969
|
+ return true
|
|
970
|
+ }
|
|
971
|
+ }
|
|
972
|
+ return false
|
|
973
|
+ }
|
|
974
|
+
|
946
|
975
|
// update or destroy all existing listeners
|
947
|
976
|
for addr := range server.listeners {
|
948
|
977
|
currentListener := server.listeners[addr]
|
|
@@ -958,13 +987,16 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
958
|
987
|
// its next Accept(). this is like sending over a buffered channel of
|
959
|
988
|
// size 1, but where sending a second item overwrites the buffered item
|
960
|
989
|
// instead of blocking.
|
|
990
|
+ tlsConfig := tlsListeners[addr]
|
|
991
|
+ isTor := isTorListener(addr)
|
961
|
992
|
currentListener.configMutex.Lock()
|
962
|
993
|
currentListener.shouldStop = !stillConfigured
|
963
|
|
- currentListener.tlsConfig = tlsListeners[addr]
|
|
994
|
+ currentListener.tlsConfig = tlsConfig
|
|
995
|
+ currentListener.isTor = isTor
|
964
|
996
|
currentListener.configMutex.Unlock()
|
965
|
997
|
|
966
|
998
|
if stillConfigured {
|
967
|
|
- logListener(addr, currentListener.tlsConfig)
|
|
999
|
+ logListener(addr, tlsConfig, isTor)
|
968
|
1000
|
} else {
|
969
|
1001
|
// tell the listener it should stop by interrupting its Accept() call:
|
970
|
1002
|
currentListener.listener.Close()
|
|
@@ -978,15 +1010,16 @@ func (server *Server) setupListeners(config *Config) (err error) {
|
978
|
1010
|
_, exists := server.listeners[newaddr]
|
979
|
1011
|
if !exists {
|
980
|
1012
|
// make new listener
|
|
1013
|
+ isTor := isTorListener(newaddr)
|
981
|
1014
|
tlsConfig := tlsListeners[newaddr]
|
982
|
|
- listener, listenerErr := server.createListener(newaddr, tlsConfig, config.Server.UnixBindMode)
|
|
1015
|
+ listener, listenerErr := server.createListener(newaddr, tlsConfig, isTor, config.Server.UnixBindMode)
|
983
|
1016
|
if listenerErr != nil {
|
984
|
1017
|
server.logger.Error("server", "couldn't listen on", newaddr, listenerErr.Error())
|
985
|
1018
|
err = listenerErr
|
986
|
1019
|
continue
|
987
|
1020
|
}
|
988
|
1021
|
server.listeners[newaddr] = listener
|
989
|
|
- logListener(newaddr, tlsConfig)
|
|
1022
|
+ logListener(newaddr, tlsConfig, isTor)
|
990
|
1023
|
}
|
991
|
1024
|
}
|
992
|
1025
|
|