[PATCH] Small trouble with multicast sockets

Samuel Tardieu <>
Wed Dec 8 18:50:57 CET 1999


I decided to play with multicast sockets in Erlang, and discovered 3
problems with the following code:

-module (tm).
-export ([test/0]).
-include_lib ("kernel/src/inet_int.hrl").
-define (MULTIADDR, {224, 225, 224, 225}).
-define (MULTIPORT, 1501).

ip4_reverse ({A, B, C, D}) -> {D, C, B, A}.

test () ->
    {ok, S} = inet_udp:open (?MULTIPORT, [{reuseadddr, 1},
			      {multicast_ttl, 16},
			      {multicast_loop, true},
			      {add_membership, {ip4_reverse (?MULTIADDR),
						{0, 0, 0, 0}}}]),
    inet_udp:send (S, ?MULTIADDR, ?MULTIPORT, "toto"),
    receive
	X ->
	    io:format ("~p~n", [X])
    end,
    inet_udp:close (S).

The three problems are:

  (1) If an option is given an invalid name, or if it has a bad
      argument, it is silently ignored. Try changing reuseaddr into
      reuseaddddr, it should succeed. *WISHLIST*

  (2) One needs to use {0, 0, 0, 0} to mean INADDR_ANY. Maybe ip_any/1
      could be exported from inet.erl so that it can be used easily.
      *WISHLIST*

  (3) On my Intel Linux box, I need to reverse the multicast group
      address given to setsockopt (..., ADD_MEMBERSHIP, ...). On my
      Sparc box, I must NOT use this address reversing. There is some
      suspicious code in inet_drv.c that may concern this:

        L_set_mreq:
            mreq_val.imr_multiaddr.s_addr = ival;
            mreq_val.imr_interface.s_addr = get_int32(ptr);

      I just wrote the following patch, but may not have the time to
      have it tested tonight (I have no Erlang semi-compiled here). If
      someone volunteers to test it, she will be welcome :) Otherwise,
      I'll give the answer tomorrow.

--- erts/emulator/drivers/common/inet_drv.c.orig	Wed Dec  8 18:46:00 1999
+++ erts/emulator/drivers/common/inet_drv.c	Wed Dec  8 18:47:22 1999
@@ -1514,8 +1514,8 @@
             type = IP_DROP_MEMBERSHIP;
             DEBUGF(("Descriptor %d:  [IPPROTO_IP] IP_DROP_MEMBERSHIP(%d)\n",desc->s,ival));
         L_set_mreq:
-            mreq_val.imr_multiaddr.s_addr = ival;
-            mreq_val.imr_interface.s_addr = get_int32(ptr);
+            mreq_val.imr_multiaddr.s_addr = sock_htonl (ival);
+            mreq_val.imr_interface.s_addr = sock_htonl (get_int32(ptr));
             ptr += 4;
             len -= 4;
             arg_ptr = (char*)&mreq_val;


  Sam




More information about the erlang-questions mailing list