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..
This commit is contained in:
Joey Hess 2016-11-21 22:03:29 -04:00
parent 2da338bb8d
commit e053f31816
No known key found for this signature in database
GPG key ID: C910D9222512E3C7

View file

@ -17,16 +17,24 @@ import Remote.Helper.P2P
import Remote.Helper.P2P.IO import Remote.Helper.P2P.IO
import Annex.UUID import Annex.UUID
import Types.UUID import Types.UUID
import Messages
import Git
import System.PosixCompat.User import System.PosixCompat.User
import Network.Socket import Network.Socket
import Control.Concurrent import Control.Concurrent
import System.Log.Logger (debugM) import System.Log.Logger (debugM)
import Control.Concurrent.STM
-- Run tor hidden service. -- Run tor hidden service.
server :: TransportHandle -> IO () server :: TransportHandle -> IO ()
server th@(TransportHandle (LocalRepo r) _) = do server th@(TransportHandle (LocalRepo r) _) = do
u <- liftAnnex th getUUID u <- liftAnnex th getUUID
q <- newTBQueueIO maxConnections
replicateM_ maxConnections $
forkIO $ forever $ serveClient u r q
uid <- getRealUserID uid <- getRealUserID
let ident = fromUUID u let ident = fromUUID u
let sock = socketFile uid ident let sock = socketFile uid ident
@ -42,9 +50,28 @@ server th@(TransportHandle (LocalRepo r) _) = do
debugM "remotedaemon" "tor hidden service running" debugM "remotedaemon" "tor hidden service running"
forever $ do forever $ do
(conn, _) <- accept soc (conn, _) <- accept soc
forkIO $ do h <- torHandle conn
debugM "remotedaemon" "handling a connection" ok <- atomically $ ifM (isFullTBQueue q)
h <- torHandle conn ( return False
_ <- runNetProtoHandle h h r (serve u) , do
writeTBQueue q h
return True
)
unless ok $ do
hClose h 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"