problem with UDP socket & recvfrom() - Unix

This is a discussion on problem with UDP socket & recvfrom() - Unix ; Hello everyone, I have a very strange problem with a UDP socket and recvfrom(). I want to use it to read-out data from an FPGA and it should work under both Linux and Mac OS X (currently I'm testing it ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: problem with UDP socket & recvfrom()

  1. problem with UDP socket & recvfrom()

    Hello everyone,

    I have a very strange problem with a UDP socket and recvfrom(). I want
    to use it to read-out data from an FPGA and it should work under both
    Linux and Mac OS X (currently I'm testing it on an intel Mac OS X
    10.4.10). While I have no problems creating and binding the socket, I
    somehow never receive any data on it, even though I'm clearly sending
    valid UDP packets to it (I verified this with ethereal) and the socket
    is definitely open and listening (checked with netstat). It doesn't
    matter whether I have the socket in blocking or non-blocking mode
    either. As I haven't implemented the UDP checksum on the FPGA side but
    set it to zero (which is clearly allowed in the RFC) I thought that
    this might be the problem, but I tried listening on port 53 (DNS) with
    exactly the same results.
    Doing some googling I found a lot of code snippets which look pretty
    much the same as mine, so by now I'm somewhat running out of ideas
    (and unfortunately it's not just my firewall blocking the port, I
    specifically opened it...) and hope that maybe someone here might be
    able to help me out.

    So here's what I'm doing in my code:
    .....
    int sockID;
    struct sockaddr_in serv_addr, cli_addr;

    char rxmsg[MAXMESG];
    int clilen,n;

    // create socket
    if ((sockID = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    cout << "socket couldn't be created, exiting..." << endl;
    return -1;
    }

    bzero((char*)&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(RXPORT);

    // bind socket
    if (bind(sockID, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
    0) {
    cout << "socket couldn't bind, exiting..." << endl;
    return -1;
    }

    int optval = 1;
    setsockopt(sockID, SOL_SOCKET, SO_RCVLOWAT, &optval,
    sizeof(SO_RCVLOWAT));
    fcntl(sockID, F_SETFL, O_NONBLOCK);

    FILE *rxdata;
    rxdata = fopen("fpgadata.test","w");
    int pktcnt = 0;
    char cmd;

    while(pktcnt<20) {
    // listen on port & dump to file
    cout << "waiting for data" << endl; // for testing only
    clilen = sizeof(cli_addr);
    n = recvfrom(sockID, rxmsg, MAXMESG, 0, (struct sockaddr
    *)&cli_addr, (socklen_t*)&clilen);
    cout << "bytes recvd: " << n << endl; // for testing only
    if (n > 0) {
    fputs(rxmsg,rxdata);
    pktcnt++;
    }
    }

    close(sockID);
    .....

    Thanks a lot & Cheers,
    Michael


  2. Re: problem with UDP socket & recvfrom()

    MNiegl wrote:
    > I have a very strange problem with a UDP socket and recvfrom(). I
    > want to use it to read-out data from an FPGA and it should work
    > under both Linux and Mac OS X (currently I'm testing it on an intel
    > Mac OS X 10.4.10). While I have no problems creating and binding the
    > socket, I somehow never receive any data on it, even though I'm
    > clearly sending valid UDP packets to it (I verified this with
    > ethereal) and the socket is definitely open and listening (checked
    > with netstat). It doesn't matter whether I have the socket in
    > blocking or non-blocking mode either. As I haven't implemented the
    > UDP checksum on the FPGA side but set it to zero (which is clearly
    > allowed in the RFC) I thought that this might be the problem, but I
    > tried listening on port 53 (DNS) with exactly the same results.


    Were you sure that something was sending port 53 traffic to your IP?
    And that it had a valid checksum?-)

    Have you also checked netstat statistics to make sure that there isn't
    some correlation between the number of no-checksum UDP datagrams
    arriving and errors being reported?

    Does MacOS X 10.4.10 make use of checksum offload features of the
    NIC(s)? Linux (2.6 at least) will. IIRC Linux still wants datagrams
    with "checksum failures" to flow up the stack, but perhaps the NIC
    under MacOS X has been told to do the actuall checking and dropping
    rather than just calculate? If there is a way to disable CKO
    (assuming it is on) on OSX you might do that. Do the same thing on
    the Linux boot.

    > Doing some googling I found a lot of code snippets which look pretty
    > much the same as mine, so by now I'm somewhat running out of ideas
    > (and unfortunately it's not just my firewall blocking the port, I
    > specifically opened it...) and hope that maybe someone here might be
    > able to help me out.


    > So here's what I'm doing in my code:
    > ....
    > int sockID;
    > struct sockaddr_in serv_addr, cli_addr;


    > char rxmsg[MAXMESG];
    > int clilen,n;


    > // create socket
    > if ((sockID = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    > cout << "socket couldn't be created, exiting..." << endl;
    > return -1;
    > }


    > bzero((char*)&serv_addr, sizeof(serv_addr));
    > serv_addr.sin_family = AF_INET;
    > serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    > serv_addr.sin_port = htons(RXPORT);


    > // bind socket
    > if (bind(sockID, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
    > 0) {
    > cout << "socket couldn't bind, exiting..." << endl;
    > return -1;
    > }


    > int optval = 1;
    > setsockopt(sockID, SOL_SOCKET, SO_RCVLOWAT, &optval,
    > sizeof(SO_RCVLOWAT));
    > fcntl(sockID, F_SETFL, O_NONBLOCK);


    For grins, drop the SO_RCVLOWAT call.

    > FILE *rxdata;
    > rxdata = fopen("fpgadata.test","w");
    > int pktcnt = 0;
    > char cmd;


    > while(pktcnt<20) {
    > // listen on port & dump to file
    > cout << "waiting for data" << endl; // for testing only
    > clilen = sizeof(cli_addr);
    > n = recvfrom(sockID, rxmsg, MAXMESG, 0, (struct sockaddr
    > *)&cli_addr, (socklen_t*)&clilen);


    What does a system call trace tool say about the parameters you are
    passing on the recvfrom call?

    > cout << "bytes recvd: " << n << endl; // for testing only
    > if (n > 0) {
    > fputs(rxmsg,rxdata);
    > pktcnt++;
    > }
    > }


    > close(sockID);
    > ....


    > Thanks a lot & Cheers,
    > Michael


    rick jones
    --
    Wisdom Teeth are impacted, people are affected by the effects of events.
    these opinions are mine, all mine; HP might not want them anyway...
    feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...

  3. Re: problem with UDP socket & recvfrom()

    ok, by now I'm fairly sure that it's because of the non-implemented
    checksum, at least on OS X. for example netstat there in the
    statistics entry for udp doesn't even show a field with no. of packets
    of without checksum (which it does in linux). but as also the number
    of dropped packets doesn't increase, I assume the packets do not even
    get recognized as udp and/or are immediately discarded. And I also
    sent UDP packets from a PC to my Mac and those were immediately
    recognized, and the only difference was the existence of the UDP
    checksum.
    The problem on OS X seems to be to disable CKO, because while FreeBSD
    allows you to do this with ifconfig, the OS X version doesn't. So I
    think the next thing is probably to set up a machine with Linux or
    FreeBSD, disable CKO and see if it then works.

    Michael

    On Oct 12, 1:35 am, Rick Jones wrote:
    > MNiegl wrote:
    > > I have a very strange problem with a UDP socket and recvfrom(). I
    > > want to use it to read-out data from an FPGA and it should work
    > > under both Linux and Mac OS X (currently I'm testing it on an intel
    > > Mac OS X 10.4.10). While I have no problems creating and binding the
    > > socket, I somehow never receive any data on it, even though I'm
    > > clearly sending valid UDP packets to it (I verified this with
    > > ethereal) and the socket is definitely open and listening (checked
    > > with netstat). It doesn't matter whether I have the socket in
    > > blocking or non-blocking mode either. As I haven't implemented the
    > > UDP checksum on the FPGA side but set it to zero (which is clearly
    > > allowed in the RFC) I thought that this might be the problem, but I
    > > tried listening on port 53 (DNS) with exactly the same results.

    >
    > Were you sure that something was sending port 53 traffic to your IP?
    > And that it had a valid checksum?-)
    >
    > Have you also checked netstat statistics to make sure that there isn't
    > some correlation between the number of no-checksum UDP datagrams
    > arriving and errors being reported?
    >
    > Does MacOS X 10.4.10 make use of checksum offload features of the
    > NIC(s)? Linux (2.6 at least) will. IIRC Linux still wants datagrams
    > with "checksum failures" to flow up the stack, but perhaps the NIC
    > under MacOS X has been told to do the actuall checking and dropping
    > rather than just calculate? If there is a way to disable CKO
    > (assuming it is on) on OSX you might do that. Do the same thing on
    > the Linux boot.
    >
    >
    >
    > > Doing some googling I found a lot of code snippets which look pretty
    > > much the same as mine, so by now I'm somewhat running out of ideas
    > > (and unfortunately it's not just my firewall blocking the port, I
    > > specifically opened it...) and hope that maybe someone here might be
    > > able to help me out.
    > > So here's what I'm doing in my code:
    > > ....
    > > int sockID;
    > > struct sockaddr_in serv_addr, cli_addr;
    > > char rxmsg[MAXMESG];
    > > int clilen,n;
    > > // create socket
    > > if ((sockID = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    > > cout << "socket couldn't be created, exiting..." << endl;
    > > return -1;
    > > }
    > > bzero((char*)&serv_addr, sizeof(serv_addr));
    > > serv_addr.sin_family = AF_INET;
    > > serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    > > serv_addr.sin_port = htons(RXPORT);
    > > // bind socket
    > > if (bind(sockID, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) <
    > > 0) {
    > > cout << "socket couldn't bind, exiting..." << endl;
    > > return -1;
    > > }
    > > int optval = 1;
    > > setsockopt(sockID, SOL_SOCKET, SO_RCVLOWAT, &optval,
    > > sizeof(SO_RCVLOWAT));
    > > fcntl(sockID, F_SETFL, O_NONBLOCK);

    >
    > For grins, drop the SO_RCVLOWAT call.
    >
    > > FILE *rxdata;
    > > rxdata = fopen("fpgadata.test","w");
    > > int pktcnt = 0;
    > > char cmd;
    > > while(pktcnt<20) {
    > > // listen on port & dump to file
    > > cout << "waiting for data" << endl; // for testing only
    > > clilen = sizeof(cli_addr);
    > > n = recvfrom(sockID, rxmsg, MAXMESG, 0, (struct sockaddr
    > > *)&cli_addr, (socklen_t*)&clilen);

    >
    > What does a system call trace tool say about the parameters you are
    > passing on the recvfrom call?
    >
    > > cout << "bytes recvd: " << n << endl; // for testing only
    > > if (n > 0) {
    > > fputs(rxmsg,rxdata);
    > > pktcnt++;
    > > }
    > > }
    > > close(sockID);
    > > ....
    > > Thanks a lot & Cheers,
    > > Michael

    >
    > rick jones
    > --
    > Wisdom Teeth are impacted, people are affected by the effects of events.
    > these opinions are mine, all mine; HP might not want them anyway...
    > feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...




  4. Re: problem with UDP socket & recvfrom()

    MNiegl wrote:
    > ok, by now I'm fairly sure that it's because of the non-implemented
    > checksum, at least on OS X. for example netstat there in the
    > statistics entry for udp doesn't even show a field with no. of
    > packets of without checksum (which it does in linux). but as also
    > the number of dropped packets doesn't increase, I assume the packets
    > do not even get recognized as udp and/or are immediately
    > discarded. And I also sent UDP packets from a PC to my Mac and those
    > were immediately recognized, and the only difference was the
    > existence of the UDP checksum.


    Sounds like it. To see if the datagram is even getting as far as IP
    you might look at the IP level stats in netstat too. And after that,
    check link-level stats if you can.

    > The problem on OS X seems to be to disable CKO, because while
    > FreeBSD allows you to do this with ifconfig, the OS X version
    > doesn't. So I think the next thing is probably to set up a machine
    > with Linux or FreeBSD, disable CKO and see if it then works.


    I wasn't even sure that OSX used CKO, just speculating If it does,
    and indeed that is the reason the reason the traffic doesn't make it
    to your app, it suggests one or two bugs which should be reported to
    Apple and/or their NIC OEM. First, the NIC should only be
    _calculating_ a checksum on the inbound traffic and not actually
    _acting_ upon it. And second, if it must act upon it, since a
    non-checksummed UDP datagram is "legal" it must recognize that.

    The second problem would be avoided so long as the NIC adheres to the
    first. IMO NICs should only do the heavy lifting, and should not be
    doing any deep thinking.

    rick jones
    --
    web2.0 n, the dot.com reunion tour...
    these opinions are mine, all mine; HP might not want them anyway...
    feel free to post, OR email to rick.jones2 in hp.com but NOT BOTH...

+ Reply to Thread