packages feed

ping 0.1.0.1 → 0.1.0.2

raw patch · 6 files changed

+82/−22 lines, 6 filesdep ~posix-api

Dependency ranges changed: posix-api

Files

CHANGELOG.md view
@@ -1,5 +1,19 @@-# Revision history for ping+# Changelog+All notable changes to this project will be documented in this file. -## 0.1.0.0 -- YYYY-mm-dd+The format is inspired by [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).+This changelog deviates from the recommendation by not grouping changes into+added, changed, deprecated, etc. subsections. -* First version. Released on an unsuspecting world.+This project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).++## [0.1.0.1] - 2018-01-07+- Fix a problem in `multihosts` that occassionally caused the function+  to wait for a number of nanoseconds close to `maxBound :: Word64`.+  This had been caused by a subtraction underflow.++## [0.1.0.0] - 2018-01-02+- Initial release.+- Function `host` for pinging a single host once.+- Function `hosts` and `range` for pinging multiple hosts once each.+- Function `multihosts` and `multirange` for pinging multiple hosts once each.
+ README.md view
@@ -0,0 +1,45 @@+# ping++## Objective++This library provides high-performance functions that issue ICMP echo+requests and wait for responses, measuring the elapsed time. It is intended+to be cross-platform as possible, and it may use any system APIs available.+However, it will not resort to running `/bin/ping` as a subprocess. Pull+requests that improve compatibility will accepted so long as they do not+start a subprocess.++## Build Instructions++This library relies on `posix-api`, which needs a currently-unreleased+version of `hsc2hs` in order to build. In order to try out this library, try:++```+~/dev $ git clone https://github.com/haskell/hsc2hs+~/dev $ cd hsc2hs+~/dev/hsc2hs $ cabal install+~/dev/hsc2hs $ cd ..+~/dev $ git clone https://github.com/andrewthad/ping+~/dev $ cd ping+~/dev/ping $ cabal new-build --with-hsc2hs=~/.cabal/bin/hsc2hs+```++This will build all dependencies, including `posix-api`, with the+upstream `hsc2hs` tool.++## Infelicities++This project's objective is to be cross-platform. However, it does not+accomplish this. The author primarily runs a Debian Linux distribution+and consequently lacks the resources and the motivation to make this+work on other platforms. Contributions to improve compatibility are+welcomed. Current known problems include:++- On Linux, the library should fallback to using raw sockets if `IPPROTO_ICMP`+  does not work.+- Support for Windows is missing.+- Support for BSD is missing. However, adding raw socket support to improve+  the situation on Linux may fix this as well.+- Support for Darwin is missing. This should not be difficult since+  Darwin supports `IPPROTO_ICMP` sockets.+
ping.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: ping-version: 0.1.0.1+version: 0.1.0.2 synopsis: icmp echo requests description:   This library provides functions that have similar behavior as the@@ -23,11 +23,12 @@ license-file: LICENSE author: Andrew Martin maintainer: andrew.thaddeus@gmail.com-copyright: 2018 Andrew Martin+copyright: 2019 Andrew Martin category: Network build-type: Simple extra-source-files:   CHANGELOG.md+  README.md   include/custom.h  flag debug@@ -45,7 +46,7 @@     , base >= 4.11.1 && <5     , ip >= 1.4     , cpu >= 0.1.2-    , posix-api >= 0.1+    , posix-api >= 0.2.1 && < 0.3     , primitive >= 0.6.4     , primitive-containers >= 0.3.1     , stm >= 2.5
src/Network/Icmp/Ping/Hosts.hs view
@@ -120,7 +120,7 @@   -> SU.Set IPv4 -- ^ Hosts   -> IO (Either IcmpException (MUU.Map IPv4 Word64)) -- ^ Elapsed nanoseconds for responding hosts hosts !pause !theHosts = do-  mask $ \restore -> SCK.socket SCK.internet SCK.datagram SCK.icmp >>= \case+  mask $ \restore -> SCK.uninterruptibleSocket SCK.internet SCK.datagram SCK.icmp >>= \case     Left (Errno e) -> pure (Left (IcmpExceptionSocket e))     Right sock -> do       durations <- restore@@ -140,8 +140,8 @@                  )         )         `onException`-        (SCK.unsafeClose sock)-      SCK.unsafeClose sock >>= \case+        (SCK.uninterruptibleClose sock)+      SCK.uninterruptibleClose sock >>= \case         Left (Errno e) -> pure (Left (IcmpExceptionClose e))         Right _ -> pure durations @@ -153,7 +153,7 @@       waitForReadWrite sock >>= \case         True -> do           debug "ready for read"-          r <- SCK.unsafeReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait+          r <- SCK.uninterruptibleReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait           case r of             Left (Errno e) -> pure (Left (IcmpExceptionReceive e))             Right receivedBytes -> if receivedBytes == intToCSize fullPacketSize@@ -185,7 +185,7 @@           pokeIcmpHeader buffer (intToWord16 ix) (getIPv4 host)           let sockaddr = SCK.encodeSocketAddressInternet                 (SocketAddressInternet { port = 0, address = toBE32 (getIPv4 host) })-          mwriteError <- SCK.unsafeSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr+          mwriteError <- SCK.uninterruptibleSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr           case mwriteError of             Left (Errno e)                 -- When you try to send a packet to a broadcast address, the kernel@@ -221,7 +221,7 @@         isReady <- waitForRead remainingMicroseconds sock         if isReady           then do-            r <- SCK.unsafeReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait+            r <- SCK.uninterruptibleReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait             case r of               Left (Errno e) -> pure (Left (IcmpExceptionReceive e))               Right receivedBytes -> if receivedBytes == intToCSize fullPacketSize
src/Network/Icmp/Ping/Multihosts.hs view
@@ -121,7 +121,7 @@ -- over the course of the loop's execution. multihosts !pause !successPause' !totalPings !cutoff !theHosts   | pause <= 0 || totalPings <= 0 || cutoff <= 0 || SU.null theHosts = pure (Right mempty)-  | otherwise = let !successPause = max successPause' 0 in mask $ \restore -> SCK.socket SCK.internet SCK.datagram SCK.icmp >>= \case+  | otherwise = let !successPause = max successPause' 0 in mask $ \restore -> SCK.uninterruptibleSocket SCK.internet SCK.datagram SCK.icmp >>= \case       Left (Errno e) -> pure (Left (IcmpExceptionSocket e))       Right sock -> do         !now0 <- getMonotonicTimeNSec@@ -155,7 +155,7 @@                          waitForRead shouldRead (word64ToInt microPause) sock >>= \case                            True -> do                              debug "Receiving in poll loop"-                             r <- SCK.unsafeReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait+                             r <- SCK.uninterruptibleReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait                              case r of                                Left (Errno e) -> pure (Left (IcmpExceptionReceive e))                                Right receivedBytes -> if receivedBytes == intToCSize fullPacketSize@@ -210,8 +210,8 @@                        )           )           `onException`-          (SCK.unsafeClose sock)-        SCK.unsafeClose sock >>= \case+          (SCK.uninterruptibleClose sock)+        SCK.uninterruptibleClose sock >>= \case           Left (Errno e) -> pure (Left (IcmpExceptionClose e))           Right _ -> pure durations @@ -269,7 +269,7 @@   let sockaddr = SCK.encodeSocketAddressInternet         (SocketAddressInternet { port = 0, address = toBE32 (getIPv4 theHost) })   mwriteError <- writeWhenReady-    (SCK.unsafeSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr)+    (SCK.uninterruptibleSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr)     (threadWaitWrite sock)   case mwriteError of     Left (Errno e)
src/Network/Icmp/Ping/Single.hs view
@@ -49,7 +49,7 @@     -- has a fancy way to display the failure. The user will likely need to     -- rerun the program with CAP_NET_RAW or as root or after adjusting     -- net.ipv4.ping_group_range with sysctl.-    mask $ \restore -> SCK.socket SCK.internet SCK.datagram SCK.icmp >>= \case+    mask $ \restore -> SCK.uninterruptibleSocket SCK.internet SCK.datagram SCK.icmp >>= \case       Left (Errno e) -> pure (Left (IcmpExceptionSocket e))       Right sock -> do         elapsed <- restore@@ -61,7 +61,7 @@                pokeIcmpHeader buffer 0 w                 start <- getMonotonicTimeNSec                mwriteError <- writeWhenReady-                 (SCK.unsafeSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr)+                 (SCK.uninterruptibleSendToMutableByteArray sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait sockaddr)                  (threadWaitWrite sock)                case mwriteError of                  Left (Errno e)@@ -75,7 +75,7 @@                        isReady <- waitForRead maxWaitTime sock                        if isReady                          then do-                           r <- SCK.unsafeReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait+                           r <- SCK.uninterruptibleReceiveFromMutableByteArray_ sock buffer 0 (intToCSize fullPacketSize) SCK.dontWait                            case r of                              Left (Errno e) -> pure (Left (IcmpExceptionReceive e))                              Right receivedBytes -> if receivedBytes == intToCSize fullPacketSize@@ -98,10 +98,10 @@           -- by unsafeClose (not that we expect to see any). We do this           -- because there is no other sensible behavior. We would much           -- rather preserve the original exception.-          (SCK.unsafeClose sock)+          (SCK.uninterruptibleClose sock)         -- It is not neccessary to use closeFdWith here since the socket         -- cannot possibly be seen by more than one thread.-        SCK.unsafeClose sock >>= \case+        SCK.uninterruptibleClose sock >>= \case           Left (Errno e) -> pure (Left (IcmpExceptionClose e))           Right _ -> pure elapsed