简体   繁体   中英

UDP socket buffer overflow detection

I'm developing cross-platform tool that captures multiple udp streams with various bit-rate. boost::asio is used for networking. Is there any way to detect the situation when the udp buffer was full and data loss on socket could take place? The only way I can see now is reading /proc/%pid%/net/udp, but it's not aplicable for windows as you know :). Also I'd like to use boost features for it if possible.

If you need this capability, you have to code it into the protocol you are using. UDP is incapable of doing this by itself. For example, you could put a sequence number in each datagram. Missing datagrams would correspond to missing sequence numbers.

I've just hit the same issue (although for me Linux-specific), and despite the question being old might as well document my findings for others.

As far as I know, there are no portable way to do this, and nothing directly supported by Boost.

That said, there are some platform-specific ways of doing it. In Linux, it can be done by setting the SO_RXQ_OVFL socket-option, and then getting the replies using recvmsg(). It's poorly documented though, but you may be helped by http://lists.openwall.net/netdev/2009/10/09/75 .

One way to avoid it in the first place is to increase the receive-buffers (I assume you've investigated it already, but including it for completeness). The SO_RCVBUF options seems fairly well-supported cross-platform. http://pubs.opengroup.org/onlinepubs/7908799/xns/setsockopt.html http://msdn.microsoft.com/en-us/library/windows/hardware/ff570832(v=vs.85).aspx OS:es puts an upper limit on this though, which an administrator might have to increase. On Linux, IE it can be increased using /proc/sys/net/core/rmem_max.

Finally, one way for your application to assess it's "load", which with large input-buffers might serve for early detection of overloading, could be to introduce a timestamp before and after the async operations. In pseudo_code (not boost::async-adapted):

work_time = 0
idle_time = 0

b = clock.now()
while running:
  a = clock.now()
  work_time += a-b
  data = wait_for_input()
  b = clock.now()
  idle_time += b-a
  process(data)

Then every second or so, you can check and reset work_time / (work_time+idle_time) . If it approaches 1, you know you're heading for trouble and can send out an alert or take other actions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM