I am trying to create a event driven multiple threads UDP/DTLS server. The design is based on the following concepts
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;
}
Add the child socket to Epoll table.
epoll_ctl(efd,EPOLL_CTL_ADD,newFd,&event);
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
}
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
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.