summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-09-16 20:35:32 -0400
committerjoe <joe@jerkface.net>2017-09-16 20:35:32 -0400
commitd034fd6bee01a1bf1e9080d16f4fd230887a792b (patch)
tree691bf843b8b9dc58cc9b2b626aaf0a47a552a568 /src/Network
parentbc0b119f7ec7ef7aa2d4faa9879633a7926bd2a6 (diff)
UPNP port requests (requires miniupnpc).
Diffstat (limited to 'src/Network')
-rw-r--r--src/Network/UPNP.hs39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/Network/UPNP.hs b/src/Network/UPNP.hs
new file mode 100644
index 00000000..fff1ba5b
--- /dev/null
+++ b/src/Network/UPNP.hs
@@ -0,0 +1,39 @@
1module Network.UPNP where
2
3import Data.Maybe
4import Network.Address (sockAddrPort)
5import Network.Socket
6import System.Directory
7import System.IO
8import System.Process as Process
9
10protocols :: SocketType -> [String]
11protocols Stream = ["tcp"]
12protocols Datagram = ["udp"]
13protocols _ = ["udp","tcp"]
14
15upnpc :: FilePath
16upnpc = "/usr/bin/upnpc"
17
18-- | Invokes the miniupnpc command line program to request ports from a UPNP
19-- wifi router. Returns the process handle on success.
20requestPorts :: String -- ^ Description stored on router, currently ignored.
21 -> [(SocketType, SockAddr)] -- ^ Protocol-port pairs to request.
22 -> IO (Maybe ProcessHandle)
23requestPorts description binds = do
24 let requests = do
25 (stype,saddr) <- binds
26 proto <- protocols stype
27 port <- maybeToList (sockAddrPort saddr)
28 [ show port, proto ]
29 bail = return Nothing
30 case requests of
31 [] -> bail
32 _ -> do
33 gotMiniUPNPC <- doesFileExist upnpc
34 if gotMiniUPNPC then do
35 phandle <- spawnProcess upnpc $ "-r" : requests
36 return $ Just phandle
37 else do
38 hPutStrLn stderr $ "Warning: unable to find miniupnpc client at "++upnpc++"."
39 bail