netdev
[Top] [All Lists]

Re: Fw: F_SETSIG broken/changed in 2.6 for UDP and TCP sockets?

To: David Stevens <dlstevens@xxxxxxxxxx>
Subject: Re: Fw: F_SETSIG broken/changed in 2.6 for UDP and TCP sockets?
From: Russell Leighton <russ@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 01 Jun 2004 18:48:28 -0400
Cc: Andrew Morton <akpm@xxxxxxxx>, netdev@xxxxxxxxxxx
In-reply-to: <OFAD1DE5B4.1A829EE7-ON88256EA6.006EE314-88256EA6.006F8B71@us.ibm.com>
References: <OFAD1DE5B4.1A829EE7-ON88256EA6.006EE314-88256EA6.006F8B71@us.ibm.com>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113
Thanks for the suggestion.

I tried using the interface itself and INADDR_ANY...the signals are not being received under 2.6 (FedoraCore2) UNLESS tcpdump is running...note this works fine under 2.4.

Below is the code fragment that sets up the socket (the previous email had the code fragment that sets up the posix rt signals on the fd), any help would be greatly appreciated:

  /* mc_fd */
  {

    /* make it */
    if ( (h->state.mc_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ) {
      aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL, "mcrxhandler cannot create socket: %s", strerror(errno));
      goto error;
    }

    /* set it to nonblocking so that this can be async */
    if ( fcntl(h->state.mc_fd,  F_SETFL, O_NONBLOCK)  == -1) {
      aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL, "mcrxhandler cannot set socket nonblocking: %s", strerror(errno));
      goto error;
    }

    /* set the mc interface */
    if ( setsockopt(h->state.mc_fd, IPPROTO_IP, IP_MULTICAST_IF, &(h->mcast_if_addr), sizeof(h->mcast_if_addr)) < 0 ) {
      u_int8_t
    *ip = (u_int8_t *)&(h->mcast_if_addr);

      aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL,
         "mcrxhandler cannot set socket IP_MULTICAST_IF for %u.%u.%u.%u: %s",
         ip[0],ip[1],ip[2],ip[4],
         strerror(errno));
      goto error;
    }

    { /* debugging where packets are going when you have many interfaces is a pain, you want to log this! */
      u_int8_t
    *ip = (u_int8_t *)&(h->mcast_if_addr);
      aw_log(h->handler_header.logger,  AW_INFO_LOG_LEVEL, "mcrxhandler running multicast on interface %u.%u.%u.%u",
         ip[0],ip[1],ip[2],ip[3]);
    }

    /* use setsockopt() to request that the kernel join a multicast group */
    {
      struct ip_mreq
    mreq;

      /* set up */
      memset(&mreq, 0 , sizeof(mreq));
      mreq.imr_multiaddr.s_addr= h->mcast_grp_addr.sin_addr.s_addr;
      mreq.imr_interface.s_addr= h->mcast_if_addr.s_addr;

      if (setsockopt(h->state.mc_fd, IPPROTO_IP,IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) {
    aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL,
           "mcrxhandler cannot set socket IPPROTO_IP,IP_ADD_MEMBERSHIP: %s", strerror(errno));
    goto error;
      }
    }

    /* so we can have many processes listening to mcast */
    {
      int32_t
    itmp = 1;
      if ( setsockopt(h->state.mc_fd, SOL_SOCKET, SO_REUSEADDR , (char *)&itmp, sizeof(itmp)) < 0 ) {
    aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL, "mcrxhandler cannot set socket SO_REUSEADDR: %s", strerror(errno));
      }
    }

    /* bind to receive messages */
    if (bind(h->state.mc_fd, (struct sockaddr *)&(h->mcast_grp_addr), sizeof(h->mcast_grp_addr)) < 0) {
      aw_log(h->handler_header.logger, AW_ERROR_LOG_LEVEL, "mcrxhandler cannot bind to multicast socket", strerror(errno));
      goto error ;
    }

    /* add callback to handle packets on mc_fd */
    aw_add_handler_fdcallback(mon, (aw_handler_t *)h, h->state.mc_fd, do_read);

  } /* end mc_fd */




David Stevens wrote:
In the udp case, I when I listen for multicast packets my app only
receives them when I am running a tcpdump (bizarre!).
    

Russ,
        This piece (which I expect has nothing to do with the other
problems you mentioned) sounds like you haven't joined the groups on
the interface on which you're receiving the multicast packets.
"tcpdump" will place the interface in "promiscuous mode" which will
receive all packets, and ordinary packet delivery will allow
the application to receive them, even if you haven't joined the group
on the relevant interface.
        To verify if the group joins is broken, you can look at
/proc/net/igmp. If the groups you're joining are not listed on the
interface you want, the program isn't joining the groups correctly.
Group membership is per-interface, so joining a group on one interface
does not join it on another.
        Feel free to contact me if you need some help debugging the
multicast problem.

                                                        +-DLS



  

<Prev in Thread] Current Thread [Next in Thread>