Mailing List Archive

[Bug 404] New: ospf_write_frags() doesn't check return value of sendmsg()
Please do not reply directly to this email. All additional
comments should be made in the comments box of this bug
report.

http://bugzilla.quagga.net/show_bug.cgi?id=404

Summary: ospf_write_frags() doesn't check return value of
sendmsg()
Product: Quagga
Version: 0.99.9
Platform: Other
OS/Version: other
Status: NEW
Severity: major
Priority: Medium
Component: ospfd
AssignedTo: paul@dishone.st
ReportedBy: web@pilot.org.ua
CC: wawa@yandex-team.ru


A FreeBSD router was running Quagga, which once was upgraded to the current
ports version (0.99.8 + patches). After that the following messages began
appearing in the logfile:

Sep 14 18:36:43 router ospfd[44680]: *** sendmsg in ospf_write failed to
A.A.A.A, id 0, off 0, len 9016, interface XXX, mtu 9000: Message too long
Sep 14 18:36:43 router ospfd[44680]: *** sendmsg in ospf_write failed to
B.B.B.B, id 0, off 0, len 9012, interface YYY, mtu 9000: Message too long

ospf_write() code examination revealed, that the most probable reason of having
msg iovector still holding data is a missing check in ospf_write_frags().
Looking at its code, it can be seen, that the return value is only checked to be
not negative. After that the input stream is adjusted to the full amount of data
requested to be sent, but not to the amount actually sent. As a result,
ospf_write_frags() always fetches all the data from the input stream, but
sometimes (on a short buffer) leaves more data in msg iovector, than was
expected. The remaining amount is then unconditionally tried to be sent by
ospf_write() and this operation sometimes fails due to the data size being too big.

The problem hasn't been seen before, because the router used to have default
buffer size of about 16KB for raw sockets. The current SO_SNDBUF adjusting code
starts with buffer size of 512 bytes and eventually grows it up to max MTU. In
such situation, chances of MTU-sized (buffer-sized, to be correct) packet of not
fitting the sending buffer raise significantly, because the buffer might still
be holding the previous data chunk. This, however, doesn't excuse
ospf_write_frags() of mishandling sendmsg() return value.

------- Additional Comments From paul@dishone.st 2007-09-14 22:30 -------
The problem hasn't been seen before because it's a new problem. :)

sendmsg() is defined to write the entire request atomically for RAW and DATAGRAM
sockets. It can't half-send the data, so if sendmsg() doesn't return an error,
the entire message must be sent.

If we're seeing an implementation writing semi-packets for this sendmsg(), then
the implementation is bust. However, that's likely not what is happening - the
bug likely is in ospfd.

Further, setting SNDBUF to /less/ than the MTU sounds like we're inviting
corner-case behaviour (at best), if it isn't a bug. How about we just allocate
n*MTU sized SNDBUFs, and reallocate in multiples of n as required?...





------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.
_______________________________________________
Quagga-bugs mailing list
Quagga-bugs@lists.quagga.net
http://lists.quagga.net/mailman/listinfo/quagga-bugs