ANN: network-alt 0.3 and hsgnutls 0.2.1

Hello network-alt 0.3 featuring: * New improved build system * Recvfrom and sendto fixes * Windows support Network-Alt is an alternative networking library for Haskell supporting a nicer API, better performance and IPv6 support. http://www.cs.helsinki.fi/u/ekarttun/network-alt hsgnutls 0.2.1 featuring: * New memory model making automatic memory management work better hsgnutls is a TLS/SSL layer built on top of the gnutls library, supporting both client and server applications. http://www.cs.helsinki.fi/u/ekarttun/hsgnutls/ - Einar Karttunen

In article <20051105110743.GA22208@yui.aoinet>,
Einar Karttunen
network-alt 0.3 featuring: * New improved build system * Recvfrom and sendto fixes * Windows support
Network-Alt is an alternative networking library for Haskell supporting a nicer API, better performance and IPv6 support.
It's quite low-level, isn't it? I wonder if it would be worth doing something along these lines: newtype IPv4Address = IPv4Address Word32 newtype IPv6Address = IPv6Address Word128 type PortNumber = Word16 data InternetService addr = MkInternetService { localAddress :: addr, sendUDP :: UDPOptions -> addr -> PortNumber -> [Word8] -> IO (), -- etc. } getIPv4Services :: IO [InternetService IPv4Address] getIPv6Services :: IO [InternetService IPv6Address] -- Ashley Yakeley, Seattle WA

On 05.11 18:29, Ashley Yakeley wrote:
It's quite low-level, isn't it? I wonder if it would be worth doing something along these lines:
newtype IPv4Address = IPv4Address Word32 newtype IPv6Address = IPv6Address Word128
This brings the question on whether they would be native or big endian - and the user would still need to use resolver API to get at these. Also the resolver API might return addresses in different address families so we would need: data Either3 a b c = First a | Second b | Third c getAddrInfo :: HostName -> PortName -> Flags -> IO [Either3 IPv4Address IPv6Address OtherAddress] while it is currently getAddrInfo :: HostName -> PortName -> Flags -> IO [(SocketType, SocketAddress)] which means applications can use addresses in different families in an uniform way.
type PortNumber = Word16
data InternetService addr = MkInternetService { localAddress :: addr, sendUDP :: UDPOptions -> addr -> PortNumber -> [Word8] -> IO (), -- etc. }
getIPv4Services :: IO [InternetService IPv4Address] getIPv6Services :: IO [InternetService IPv6Address]
Does it make sense to have the address type in there? Most of the time high level applications should not care whether the socket is IPv4 or IPv6 (or something entirely else). One of my main goals has been to make the protocols transparent - changing from IPv4 to being protocol agnostic should be as easy as possible. The API you are suggesting would be certainly quite easy to implement on top of the current one. If you can specify the interface you would like I think I can include something like that in the next release... Currently the code would look like: sendTCPTo hostname port data = do s <- connectTCP hostname port sendString s data sendUDPTo hostname addressType port data = do let st = SocketType addressType sockDgram 0 s <- socket st ((cst,csa):_) <- getAddrInfo hostname port 0 st connect s csa sendString s data sendUDPv4 host port data = sendUDPTo host afInet port data sendUDPv6 host port data = sendUDPTo host afInet6 port data sendUDPAny host port data= sendUDPTo host afUnspec port data Adding a function like connectTCP for UDP would be very easy, but in practise most of the UDP code I have worked with was interested in the low level details. - Einar Karttunen

In article <20051106102654.GA4531@yui.aoinet>,
Einar Karttunen
On 05.11 18:29, Ashley Yakeley wrote:
It's quite low-level, isn't it? I wonder if it would be worth doing something along these lines:
newtype IPv4Address = IPv4Address Word32 newtype IPv6Address = IPv6Address Word128
This brings the question on whether they would be native or big endian -
This should be unambiguous. For instance, in the address 127.0.0.1, 127 is the high Word8 of the Word32.
and the user would still need to use resolver API to get at these.
That could be a function in InternetService: type DomainName = String data InternetService addr = MkInternetService { ... dnsLookup :: DomainName -> IO (Maybe addr), -- or similar ... }
Does it make sense to have the address type in there? Most of the time high level applications should not care whether the socket is IPv4 or IPv6 (or something entirely else). One of my main goals has been to make the protocols transparent - changing from IPv4 to being protocol agnostic should be as easy as possible.
This is a good application for polymorphism on the address type.
The API you are suggesting would be certainly quite easy to implement on top of the current one. If you can specify the interface you would like I think I can include something like that in the next release...
What you have is close to the C sockets API. It's probably best not to mix the high-level and low-level stuff. Probably there should be some wider discussion on what the best approach is, especially as there's some impetus for reform of the file APIs also. -- Ashley Yakeley, Seattle WA

On 11/7/05, Ashley Yakeley
This brings the question on whether they would be native or big endian -
This should be unambiguous. For instance, in the address 127.0.0.1, 127 is the high Word8 of the Word32.
I vote for this. Having Haskell values in Network order is awkward, especially if you can't treat them as opaque. For example, my DNS library would be pure Haskell, if I didn't have to import htonl and friends. The extra htonl's on network operations shouldn't cost too much, and we have type-system to ensure that the conversion is done consistently.
Does it make sense to have the address type in there? Most of the time high level applications should not care whether the socket is IPv4 or IPv6 (or something entirely else).
Sometimes applications exchange host addresses between themselves, consider a distributed system like DNS or a peer-to-peer network. Best regards Tomasz

On 07.11 08:16, Tomasz Zielonka wrote:
Does it make sense to have the address type in there? Most of the time high level applications should not care whether the socket is IPv4 or IPv6 (or something entirely else).
Sometimes applications exchange host addresses between themselves, consider a distributed system like DNS or a peer-to-peer network.
Which is entirely possible. Just use getHost and getService - they should produce values which can be fed back to getAddrInfo. Here is a scetch of a higher level API, does this implement what you were after - and how to make this better? newtype IPv4Address = IPv4 Word32 newtype IPv6Address = IPv6 Word128 newtype UnixAddress = Unix String -- Find a better name newtype AnyAddress = AnyAddr (SocketType,SocketAddress) class Resolver addrt where resolve :: String -> Flags -> IO [addrt] resolveReverse :: addrt -> Flags -> IO [String] instance Resolver IPv4Address where ... -- And the same for the rest type Service = String -- or would Word16 be better? class Connect addr where connectStream :: addrt -> Service -> IO Socket connectDgram :: addrt -> Service -> IO Socket sendDGramString :: addrt -> Service -> String -> IO () - Einar Karttunen

On Mon, Nov 07, 2005 at 12:01:25PM +0200, Einar Karttunen wrote:
Which is entirely possible. Just use getHost and getService - they should produce values which can be fed back to getAddrInfo.
IIUC, you suggest to send the String representation of an address? For some applications it might be OK, but what about already established protocols?
[...]
I wanted to get the repository to see the code, but there is some problem, probably with permissions: tomekz@lambda:~/devel/haskell/libs$ darcs get http://www.cs.helsinki.fi/u/ekarttun/network-alt/network-alt Copying patch 1 of 55... darcs failed: Failed to download URL http://www.cs.helsinki.fi/u/ekarttun/network-alt/network-alt/_darcs/patches/... libcurl: HTTP error (404?) The error message suggests error 404, but when I explored the repo with links I got 403 on this file. Best regards Tomasz

On 2005-11-07, Tomasz Zielonka
On 11/7/05, Ashley Yakeley
wrote: This brings the question on whether they would be native or big endian -
This should be unambiguous. For instance, in the address 127.0.0.1, 127 is the high Word8 of the Word32.
I vote for this. Having Haskell values in Network order is awkward, especially if you can't treat them as opaque. For example, my DNS library would be pure Haskell, if I didn't have to import htonl and friends.
You don't have to: just serialize a 32-bit int into octets by shifting and adding manually. -- Aaron Denney -><-
participants (4)
-
Aaron Denney
-
Ashley Yakeley
-
Einar Karttunen
-
Tomasz Zielonka