* [Caml-list] IPv6 zone-id @ 2014-07-09 17:35 Vincent B. 2014-07-11 8:03 ` Raphaël Proust 0 siblings, 1 reply; 7+ messages in thread From: Vincent B. @ 2014-07-09 17:35 UTC (permalink / raw) To: caml-list Hi, The Unix module does not make possible to use IPv6 link-local addresses. This is due to the fact that the "sockaddr" type in Unix is not as complete as its C counterpart, especially it lacks zone-id information that is required to use such addresses. Since I needed such features, I started writing a library (http://github.com/vbmithr/ocaml-sockopt), unfortunately, given that every networking piece of code written in OCaml use the primitives of the Unix module, I would have to patch all networking code I want to use which is not very convenient. So I'm in the process of writing a patch for OCaml and I'm taking the approach of extending the sockaddr type like this: type sockaddr_raw (* a real struct sockaddr *) type sockaddr = ADDR_UNIX of string | ADDR_INET of inet_addr * int | ADDR_RAW of sockaddr_raw And then upgrading all the Unix code that uses type sockaddr. This approach seems to me the most conservative towards existing code. Should I continue in this direction or this design is not the optimal one ? Cheers, Vincent ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] IPv6 zone-id 2014-07-09 17:35 [Caml-list] IPv6 zone-id Vincent B. @ 2014-07-11 8:03 ` Raphaël Proust 2014-07-11 14:13 ` Vincent B. 0 siblings, 1 reply; 7+ messages in thread From: Raphaël Proust @ 2014-07-11 8:03 UTC (permalink / raw) To: Vincent B.; +Cc: OCaml Mailing List On Wed, Jul 9, 2014 at 6:35 PM, Vincent B. <vb@luminar.eu.org> wrote: > The Unix module does not make possible to use IPv6 link-local > addresses. > > This is due to the fact that the "sockaddr" type in Unix is not as > complete as its C counterpart, especially it lacks zone-id information > that is required to use such addresses. > > Since I needed such features, I started writing a library > (http://github.com/vbmithr/ocaml-sockopt), unfortunately, given that > every networking piece of code written in OCaml use the primitives of > the Unix module, I would have to patch all networking code I want to > use which is not very convenient. Is it possible to make a new networking module using Cstruct to manage sockaddr and such? > > So I'm in the process of writing a patch for OCaml and I'm taking the > approach of extending the sockaddr type like this: > > type sockaddr_raw (* a real struct sockaddr *) > > type sockaddr = > ADDR_UNIX of string > | ADDR_INET of inet_addr * int > | ADDR_RAW of sockaddr_raw > > And then upgrading all the Unix code that uses type sockaddr. > > This approach seems to me the most conservative towards existing > code. Should I continue in this direction or this design is not the > optimal one ? Although very conservative towards the existing codebases, I don't like this approach for the following reasons. The same sockaddr can be represented in different ways (which means that equality becomes non-trivial, and the choice of representation is non-obvious for programmers). The Unix module is build as abstractions from the underlying system, adding a sockaddr_raw defeats that. It becomes abstractionless. Additionally, is sockaddr_raw completely opaque? what constructors/destructors are available? Cheers, -- ______________ Raphaël Proust ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] IPv6 zone-id 2014-07-11 8:03 ` Raphaël Proust @ 2014-07-11 14:13 ` Vincent B. 2014-07-11 19:25 ` Vincent B. 0 siblings, 1 reply; 7+ messages in thread From: Vincent B. @ 2014-07-11 14:13 UTC (permalink / raw) To: Raphaël Proust; +Cc: caml-list On 11/07/2014 10:03, Raphaël Proust wrote: > On Wed, Jul 9, 2014 at 6:35 PM, Vincent B. <vb@luminar.eu.org> wrote: >> > The Unix module does not make possible to use IPv6 link-local >> > addresses. >> > >> > This is due to the fact that the "sockaddr" type in Unix is not as >> > complete as its C counterpart, especially it lacks zone-id information >> > that is required to use such addresses. >> > >> > Since I needed such features, I started writing a library >> > (http://github.com/vbmithr/ocaml-sockopt), unfortunately, given that >> > every networking piece of code written in OCaml use the primitives of >> > the Unix module, I would have to patch all networking code I want to >> > use which is not very convenient. > Is it possible to make a new networking module using Cstruct to manage > sockaddr and such? Not sure what you mean by "using Cstruct to manage sockaddr…" but yeah, it is just a matter of binding the relevant C primitives. The Unix module is far from exhaustive, yet it is the normal entry point for doing networking in OCaml. The issue here is to be able to use existing networking OCaml code. >> > >> > So I'm in the process of writing a patch for OCaml and I'm taking the >> > approach of extending the sockaddr type like this: >> > >> > type sockaddr_raw (* a real struct sockaddr *) >> > >> > type sockaddr = >> > ADDR_UNIX of string >> > | ADDR_INET of inet_addr * int >> > | ADDR_RAW of sockaddr_raw >> > >> > And then upgrading all the Unix code that uses type sockaddr. >> > >> > This approach seems to me the most conservative towards existing >> > code. Should I continue in this direction or this design is not the >> > optimal one ? > Although very conservative towards the existing codebases, I don't > like this approach for the following reasons. > > The same sockaddr can be represented in different ways (which means > that equality becomes non-trivial, and the choice of representation is > non-obvious for programmers). That is indeed an issue. > The Unix module is build as abstractions from the underlying system, > adding a sockaddr_raw defeats that. It becomes abstractionless. This is an issue as well. > Additionally, is sockaddr_raw completely opaque? what > constructors/destructors are available? Unix.getifaddrs would return a RAW sockaddr for example. You raise valid points. The best approach IMO would be to extend the abstraction to accomodate for the other features. The root issue is that type sockaddr in OCaml is not abstracting enough of the C interface: A struct sockaddr is more than what is abstracted from it. Changing the type sockaddr in OCaml would break all existing networking code. That's why I was looking for advice basically. I'm gonna look for alternative OCaml stdlib to see if there is anything better for networking. Thanks for you answer :) Vincent ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] IPv6 zone-id 2014-07-11 14:13 ` Vincent B. @ 2014-07-11 19:25 ` Vincent B. 2014-07-16 16:04 ` Francis Dupont 0 siblings, 1 reply; 7+ messages in thread From: Vincent B. @ 2014-07-11 19:25 UTC (permalink / raw) To: caml-list Actually I have another idea (looking at how janestreet core made their mcast_{join,leave} functions: Why not passing an optional argument (in UnixLabels) for ifname to connect/bind functions ? This would be not bad I think. Opinions anyone ? Vincent ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] IPv6 zone-id 2014-07-11 19:25 ` Vincent B. @ 2014-07-16 16:04 ` Francis Dupont 2014-07-17 9:48 ` Vincent B. 0 siblings, 1 reply; 7+ messages in thread From: Francis Dupont @ 2014-07-16 16:04 UTC (permalink / raw) To: Vincent B.; +Cc: caml-list In your previous mail you wrote: > Actually I have another idea (looking at how janestreet core made their mcas > t_{join,leave} functions: > > Why not passing an optional argument (in UnixLabels) for ifname to connect/b > ind functions ? > > This would be not bad I think. Opinions anyone ? => I disagree: the zone-id is a member of the address, not an extra to system calls using addresses. Regards Francis.Dupont@fdupont.fr ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] IPv6 zone-id 2014-07-16 16:04 ` Francis Dupont @ 2014-07-17 9:48 ` Vincent B. 2014-07-17 10:51 ` David Allsopp 0 siblings, 1 reply; 7+ messages in thread From: Vincent B. @ 2014-07-17 9:48 UTC (permalink / raw) To: caml-list On 16/07/2014 18:04, Francis Dupont wrote: > => I disagree: the zone-id is a member of the address, not an extra > to system calls using addresses. > > Regards Agreed. My new proposition: make "type sockaddr" include flow_info and scope_id/zone_id This would break existing code. Vincent ^ permalink raw reply [flat|nested] 7+ messages in thread
* RE: [Caml-list] IPv6 zone-id 2014-07-17 9:48 ` Vincent B. @ 2014-07-17 10:51 ` David Allsopp 0 siblings, 0 replies; 7+ messages in thread From: David Allsopp @ 2014-07-17 10:51 UTC (permalink / raw) To: caml-list Vincent B. wrote: > On 16/07/2014 18:04, Francis Dupont wrote: > > => I disagree: the zone-id is a member of the address, not an extra to > > system calls using addresses. > > > > Regards > > Agreed. My new proposition: make "type sockaddr" include flow_info and > scope_id/zone_id > > This would break existing code. Two thoughts (one pure, one rather evil) on mechanisms which might not break existing code: Given that the type inet_addr is abstract, and changing ADDR_INET is not desirable, a pure "trick" to maintain compatibility could be done with the type of inet_addr in Unix.ml where instead of being string it becomes string * int option * int option or something like that. You can then add an extra function, ipv6_sockaddr with type inet_addr * int * int * int such that [ipv6_sockaddr address port flow scope] returns [ADDR_INET((#1 address, Some flow, Some scope), port)] and some kind of helper function ipv6_getsockaddr : sockaddr -> string * int option * int option. That prevents existing code which expects ADDR_INET to have two values only from breaking but it does now mean that two inet_addr values will be non-equal based on a socket parameter which isn't great. Another "solution" is to sacrifice one's soul on the altar of backwards compatibility and invoke Obj! Along the lines of: type sockaddr = ... type sockaddr_internal = ADDR_UNIX_INT of string | ADDR_INET_INT of inet_addr * int * int * int and then ipv6_sockaddr is defined as follows: let ipv6_sockaddr inet_addr port flow scope = if domain_of_sockaddr inet_addr <> PF_INET6 then invalid_arg "Unix.ipv6_sockaddr" else if flow = 0 && scope = 0 then ADDR_INET(inet_addr, port) else (Obj.magic (ADDR_INET_INT(inet_addr, port, flow, scope)) : sockaddr) let ipv6_getsockaddr sockaddr = match sockaddr with ADDR_INET(addr, port) -> if is_inet6_addr addr then if Obj.size (Obj.repr sockaddr) = 2 then (addr, port, 0, 0) else let (addr, port, flow, scope) = (Obj.magic sockaddr : (inet_addr * int * int * int)) in (addr, port, flow, scope) else invalid_arg "Unix.ipv6_getsockaddr" | _ -> invalid_arg "Unix.ipv6_getsockaddr" Now you have a sockaddr type where differing flow and scope values will result in different sockaddr values (= good). The only thing (I think!) which this breaks, is C code which tests the block size of an ADDR_INET value instead of its tag... but that's a really odd thing to do. Obviously, a different runtime would also suffer - but the whole of Unix has to be rewritten for a different runtime anyway (JavaScript, HVLM, etc.) so that's maybe not so much of an issue. The only weirdness is then needing a function to break apart the IPv6 parameters, but that seems to be unavoidable if your aim is backwards compatibility. I should probably take a shower after writing that code, though... David ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-07-17 10:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2014-07-09 17:35 [Caml-list] IPv6 zone-id Vincent B. 2014-07-11 8:03 ` Raphaël Proust 2014-07-11 14:13 ` Vincent B. 2014-07-11 19:25 ` Vincent B. 2014-07-16 16:04 ` Francis Dupont 2014-07-17 9:48 ` Vincent B. 2014-07-17 10:51 ` David Allsopp
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox