cac6e7698b7beea11b807384dd00aaa0bed3c5b4

"pid" is not "process id" in netlink, but rather, "port id". If you bind to a sockaddr == 0 then Linux automatically assigns your socket a port id - which happens to be the same as the process ID for the first one concurrently open. For the second and subsequent concurrently-open sockets, binding 0 (as most users of this library will do) gets you back a random high-numbered port id. This change preserves the existing use case (one port open in the process, binding to 0) while fixing multiple-ports-open-in-the-same-process, socket-is- passed-in-and-pid-is-not-specified, and specific-pid-is-requested-but-could- not-bind-to-it. We're probably still not thread-safe - the seq handling looks dodgy - but at least now we can use multiple sockets in separate threads and have them all work. Using the same socket from multiple threads is a slightly niche use case, and it's tempting to say "don't do this" instead...
Ruby Netlink ============ This library provides an API for using a Linux Netlink socket, for doing things like manipulating IP interfaces and routes programmatically, and capturing packets from ULOG. Example ======= require 'linux/netlink/route' ip = Linux::Netlink::Route::Socket.new # Info about eth0 interface p ip.link["eth0"] # Addresses on eth0 interface ip.addr.list(:index=>"eth0") do |addr| puts addr.address end See the examples/ and test/ directories for more examples. Requirements ============ ruby 1.9 (tested with ruby 1.9.2), OR ruby 1.8.7 with the ffi library. Code organisation ================= There are separate classes for each Netlink protocol providing a high-level API. These all in turn use the NLSocket class, which has methods for adding the headers to messages and sending them over a socket. The messages themselves are built using class Message or RtattrMessage, which in turn are subclasses of CStruct, which performs the low-level packing and unpacking of the message bodies. LinkHandler/ AddrHandler/ VlanHandler/ RouteHandler | v Route Firewall NFLog ...etc | | | +-------+-------+ | v NLSocket | v Message / RtattrMessage | v CStruct Useful reference material ========================= * http://www.linuxjournal.com/article/7356 * http://people.redhat.com/nhorman/papers/netlink.pdf * apt-get source iproute Note there are some errors in the nhorman paper. On page 8/9, it says nlmsg_pid ... Also note that it is imperative that any program receiving netlink socket messages from the kernel verify that this field is set to zero, or it is possible to expose the software to unexpected influences from other non-privlidged user space programs. However, what really needs to be checked is the pid in the sockaddr_nl structure returned by recvmsg msghdr, as shown by this code in lib/libnetlink.c: struct msghdr msg = { .msg_name = &nladdr, .msg_namelen = sizeof(nladdr), .msg_iov = &iov, .msg_iovlen = 1, }; ... status = recvmsg(rth->fd, &msg, 0); ... if (nladdr.nl_pid != 0 || h->nlmsg_pid != rth->local.nl_pid || h->nlmsg_seq != rth->dump) { TODO ==== * Exception hierarchy * More tests * More netlink protocols Copyright ========= (C) 2011 Bytemark Hosting Written by Brian Candler <B.Candler@pobox.com> Distribute under the same terms as Ruby http://www.ruby-lang.org/en/LICENSE.txt
Description
Languages
Ruby
100%