caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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;
as well as URLs for NNTP newsgroup(s).