We help IT Professionals succeed at work.

No buffer space available on RAW socket

Chules
Chules asked
on
1,962 Views
Last Modified: 2012-05-05
Hello,
I'm programming an application that uses raw C raw sockets to send out some data.  I am only concerned with the program's workings under Linux, and this problem could very well be OS-specific.
I need to send out a lot of raw data quickly, but when I try to send out too much too fast, sendto() fails with "No buffer space available".  I do not get this error when I add a sleep function in between sending each packet, but because of the timer granularity, it cannot send nearly as fast as I need it to.
Looking at the Linux man page for sendto(), it says that this error does not normally occur on Linux and the packets are just silently dropped, but this error is occurring.
My question is how do I stop getting this error and still send packets at a very fast rate.  The preferable solution would be to have sendto() block until the buffer space was available (or to poll the buffer space before calling sendto() to make sure there is enough) but just making it silently drop the packets could also work.
Thanks a lot,
Chules
Comment
Watch Question

Commented:
is this a UDP or TCP socket?

If it's a UDP socket, packet loss is to be expected, if not inside the system, then on the network.  So this buffer full situation is the least of your worries-- you must write your code in such a way that packet loss is either detected and recovered from, or somehow handled without causing things to crash or robots to go on a shooting spree.

If it's TCP, not a problem-- you just resend the data.   TCP ensures there's no data lost.

On some systems you can tweak a kernel parameter to increase the buffer sizes-- that may help.

ALso what is the SIZE of each sendto() buffer?   If you send HUGE bufferloads, the system may temporarily be unable to digest the whole buffer, while it might have been able to swallow a smaller buffer.  If you get the error message, I'd try cutting back the buffer sie to say half and see if that works.  A nicve dynamic bufffer sizing algorithm would be a good thing to try.  Something like, start at BufSize = 4096 or somesuch, then if you get the "cant send this" error return, do a BufSize /=2 and try sending again, then if the send succeeds, every 10th write try BufSize *= 2 and see if that works....

Author

Commented:
The socket is neither TCP nor UDP ... it's a raw socket, but I am sending TCP packets (or at least the TCP packets sufficient for the handshake).  I'm not sure that packets are being lost though, as it sends of data at 1.5mbps max (according to iptraf) and the network has a 100mbit internal connection and a 10mbit connection to the WAN.
If I were to implement a dynamic buffering algorithm, how would I change the buffer size?  Or read the initial size?

Commented:
Is there some really good reason you're using raw sockets to send TCP packets?

From personal experience, it's really hard to write your own TCP stack, especially if you want it to handle all the difficult cases, such as network congestion, lost packets, retransmits, packet fragmentation, and Nagel.

Please consider using regular TCP packets-- there's 100's of person-years that's been devoted to getting TCP to work well.



Author

Commented:
I need to use raw sockets for speed and control over headers, normal TCP sockets don't give the kind of control needed for this particular application.
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
Overhead isn't the problem, it's that I'm not creating an entire TCP session.  If I wanted an entire connection with transferring data and such, I would definitely use connect() and TCP sockets, but I need to send individual manually crafted packets, not even part of an existing stream.  I'm not trying to code a TCP stack, just sending out raw packets that happen to use the same headers as TCP packets.

Commented:
> but I need to send individual manually crafted packets, not even part of an existing stream.

Would that mean you want to start a Denial-of-service attack?

Author

Commented:
O.o
Of course not.  If I wanted to send a SYN flood or something I'd just use one of the many script kiddie tools all over the internet that do just that.  I'm trying to make a tool similar to nmap to check internal networks for open Kazaa, BitTorrent, and other P2P ports, but quickly.

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.