aboutsummaryrefslogtreecommitdiff
path: root/RemoteDaemon
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-11-21 22:03:29 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-11-21 22:03:29 -0400
commit4cf9d7f04e0b42a78502614a28cc8460aba9df9c (patch)
tree5d2bfad2efb00695220855709eb82ec23650b72c /RemoteDaemon
parent39b01141b8f24e780ba579c06adc80372a1b82d7 (diff)
avoid serving more than 10 tor connections at a time
Another 10 clients can be accepted and waiting their turn. After that, start dropping connections. This is to avoid DOS attacks..
Diffstat (limited to 'RemoteDaemon')
-rw-r--r--RemoteDaemon/Transport/Tor.hs37
1 files changed, 32 insertions, 5 deletions
diff --git a/RemoteDaemon/Transport/Tor.hs b/RemoteDaemon/Transport/Tor.hs
index f28a2c6fd..f8dfede10 100644
--- a/RemoteDaemon/Transport/Tor.hs
+++ b/RemoteDaemon/Transport/Tor.hs
@@ -17,16 +17,24 @@ import Remote.Helper.P2P
import Remote.Helper.P2P.IO
import Annex.UUID
import Types.UUID
+import Messages
+import Git
import System.PosixCompat.User
import Network.Socket
import Control.Concurrent
import System.Log.Logger (debugM)
+import Control.Concurrent.STM
-- Run tor hidden service.
server :: TransportHandle -> IO ()
server th@(TransportHandle (LocalRepo r) _) = do
u <- liftAnnex th getUUID
+
+ q <- newTBQueueIO maxConnections
+ replicateM_ maxConnections $
+ forkIO $ forever $ serveClient u r q
+
uid <- getRealUserID
let ident = fromUUID u
let sock = socketFile uid ident
@@ -42,9 +50,28 @@ server th@(TransportHandle (LocalRepo r) _) = do
debugM "remotedaemon" "tor hidden service running"
forever $ do
(conn, _) <- accept soc
- forkIO $ do
- debugM "remotedaemon" "handling a connection"
- h <- torHandle conn
- _ <- runNetProtoHandle h h r (serve u)
+ h <- torHandle conn
+ ok <- atomically $ ifM (isFullTBQueue q)
+ ( return False
+ , do
+ writeTBQueue q h
+ return True
+ )
+ unless ok $ do
hClose h
- debugM "remotedaemon" "done handling a connection"
+ warningIO "dropped TOR connection, too busy"
+
+-- How many clients to serve at a time, maximum. This is to avoid DOS
+-- attacks.
+maxConnections :: Int
+maxConnections = 10
+
+serveClient :: UUID -> Repo -> TBQueue Handle -> IO ()
+serveClient u r q = bracket setup cleanup go
+ where
+ setup = atomically $ readTBQueue q
+ cleanup = hClose
+ go h = do
+ debugM "remotedaemon" "serving a TOR connection"
+ void $ runNetProtoHandle h h r (serve u)
+ debugM "remotedaemon" "done with TOR connection"