From 4cf9d7f04e0b42a78502614a28cc8460aba9df9c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Mon, 21 Nov 2016 22:03:29 -0400 Subject: 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.. --- RemoteDaemon/Transport/Tor.hs | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'RemoteDaemon') 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" -- cgit v1.2.3