2
votes

I am trying to create a event driven multiple threads UDP/DTLS server. The design is based on the following concepts

  1. Have a UDP socket where the Clients connects on
  2. Use Epoll to ask for events on the UDP listen socket.
  3. The UDP socket acts as a TCP listen socket and creates child fds that connect to the specific client. For this I have implemented a UDPAccept method for my object which has the pseudo code as shown below

    UDPAccept(int fd,struct sockaddr * addr,
       socklen_t * addr_len,void *sockBuf,size_t *read)
    {
        //sanity checks
        int childfd = -1;
        int error = 1;
        socklen_t localLen,peerLen;
        int family;
        struct sockaddr_in         local4,peer4;
        struct sockaddr            temp;
        size_t maxLen = 65535;
        getsockname(fd,(struct sockaddr *)&temp,&localLen);
        family = temp.sa_family;
        do
        {
         childfd = socket(family,SOCK_DGRAM,0);
         //error handling       
         //handle IPV6 
         local4 = (sockaddr_in *)temp;
         error = recvfrom( fd, sockBuf,
                            maxLen,0,(struct sockaddr *)&peer4,
                                             &peerLen);
         error = bind(childfd,(struct sockaddr *)&local4,sizeof local4);
         error = connect(childfd,(struct sockaddr *)&peerV4,peerLen);
        //handle error      
       }while(0);
       if(addr != NULL && addr_len != NULL)
       {
        *addr_len = peerLen;
        addr = &peerV4;
        *read = error;
       }    
       // error handling and cleanup
       return childfd;
    }
    
  4. Add the child socket to Epoll table.

    epoll_ctl(efd,EPOLL_CTL_ADD,newFd,&event);
    
  5. Poll for events on the child and listen socket

    currentSize = epoll_wait(efd,events,MAX_SOCKET_FD,timeout);
    //handle errors
    for(i = 0; i < currentSize;i++)
    {
    
        if(events[i].data.fd == listenUDP)
            //call UDPAccept
            // update local tables
       else
            //handle child fd events
    }
    
  6. Have multiple threads to the same thing, synchronize using locks during accept

Now my question is will epoll stop giving me POLLIN events on the listening socket because I have created a new UDP child connected socket to the client or will I have to handle it myself

2

2 Answers

4
votes

It will deliver events on both sockets unless you remove the first socket from events.

But I'm wondering why you're doing this. You can use a single UDP socket for everything. It's much simpler.

0
votes

Per the Linux man page on connect(), a filter will ensure only datagrams from the "connected" peer will be delivered to the new socket.

One caveat though... The bind() call will briefly take over the port from the listener until the connect call(). It's a small window, but can result in datagrams from other clients appearing on the "connected" socket. You can ignore them by validating the peer address.