http://www.mediawiki.org/wiki/Special:Code/MediaWiki/100788

Revision: 100788
Author:   tstarling
Date:     2011-10-26 04:49:14 +0000 (Wed, 26 Oct 2011)
Log Message:
-----------
* Moved the multicast join function out of the generic Socket class and into 
UDPSocket where it belongs, renamed it to JoinMulticast. Have it accept an 
IPAddress instead of char* per convention.
* Rewrote JoinMulticast, implemented IPv6 multicast group join support.
* Fixed the non-functional char* constructor of IPAddress.
* Added a constructor from std::string to IPAddress, for convenience.
* Added some IPAddress wrappers for INADDR_ANY and in6addr_any.
* Sprinkled in some const modifiers.
* Enforced the non-copyable nature of Socket with a private constructor.
* Enforced the fact that Socket is a pure base class and should not be 
instantiated, by making all constructors private or protected.
* In udp2log, fixed the ridiculous attempt at polymorphic object construction 
introduced in r75452, mimicked in r95725.
* Moved -lboost_program_options to the end of the object list, the linker now 
seems to want this.

Modified Paths:
--------------
    trunk/udplog/Makefile
    trunk/udplog/srclib/IPAddress.cpp
    trunk/udplog/srclib/IPAddress.h
    trunk/udplog/srclib/Socket.cpp
    trunk/udplog/srclib/Socket.h
    trunk/udplog/srclib/SocketAddress.h
    trunk/udplog/udp2log/udp2log.cpp

Modified: trunk/udplog/Makefile
===================================================================
--- trunk/udplog/Makefile       2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/Makefile       2011-10-26 04:49:14 UTC (rev 100788)
@@ -17,7 +17,7 @@
        g++ $(CFLAGS) $(HOST_OBJS) -o host
 
 log2udp: $(LOG2UDP_OBJS)
-       g++ $(CFLAGS) -lboost_program_options $(LOG2UDP_OBJS) -o log2udp
+       g++ $(CFLAGS) $(LOG2UDP_OBJS) -lboost_program_options -o log2udp
 
 udprecv: $(UDPRECV_OBJS)
        g++ $(CFLAGS) -Wall $(UDPRECV_OBJS) -o udprecv
@@ -29,7 +29,7 @@
        g++ $(CFLAGS) -o packet-loss srcmisc/packet-loss.cpp
 
 udp2log/udp2log: $(UDP2LOG_OBJS)
-       g++ $(CFLAGS) -o udp2log/udp2log -lboost_program_options 
$(UDP2LOG_OBJS) 
+       g++ $(CFLAGS) -o udp2log/udp2log $(UDP2LOG_OBJS) -lboost_program_options
 
 install:
        install log2udp $(DESTDIR)/usr/bin/log2udp

Modified: trunk/udplog/srclib/IPAddress.cpp
===================================================================
--- trunk/udplog/srclib/IPAddress.cpp   2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/srclib/IPAddress.cpp   2011-10-26 04:49:14 UTC (rev 100788)
@@ -2,6 +2,9 @@
 #include "Exception.h"
 #include "SocketAddress.h"
 
+const IPAddress IPAddress::any4(INADDR_ANY);
+const IPAddress IPAddress::any6(&in6addr_any);
+
 std::string & IPAddress::ToString()
 {
        if (!presentation.size()) {
@@ -19,8 +22,17 @@
        return presentation;
 }
 
-IPAddress::IPAddress(int type, char *presentation)
+void IPAddress::InitFromString(const char *presentation)
 {
+       domain = PF_INET;
+       if (strstr(presentation, ":")) {
+               type = AF_INET6;
+               length = sizeof(in6_addr);
+       } else {
+               type = AF_INET;
+               length = sizeof(in_addr);
+       }
+
        int ret = inet_pton(type, presentation, &data);
        if (!ret ) {
                throw std::runtime_error("Invalid IP address");

Modified: trunk/udplog/srclib/IPAddress.h
===================================================================
--- trunk/udplog/srclib/IPAddress.h     2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/srclib/IPAddress.h     2011-10-26 04:49:14 UTC (rev 100788)
@@ -5,6 +5,8 @@
 #include <netinet/in.h>
 #include <string>
 #include <boost/shared_ptr.hpp>
+#include <stdexcept>
+#include <memory.h>
 
 class SocketAddress;
 
@@ -13,13 +15,13 @@
        IPAddress()
                : type(AF_INET), domain(PF_INET), length(sizeof(in_addr)) {}
 
-       IPAddress(struct in_addr * src) 
+       IPAddress(const struct in_addr * src) 
                : type(AF_INET), domain(PF_INET), length(sizeof(in_addr))
        { 
                data.v4 = *src;
        }
 
-       IPAddress(struct in6_addr * src) 
+       IPAddress(const struct in6_addr * src) 
                : type(AF_INET6), domain(PF_INET6), length(sizeof(in6_addr))
        {
                data.v6 = *src;
@@ -31,16 +33,34 @@
                data.v4.s_addr = addr;
        }
 
-       IPAddress(int type, char * presentation);
+       IPAddress(const char * presentation) {
+               InitFromString(presentation);
+       }
 
-       void* GetBinaryData() { return &data; }
-       size_t GetBinaryLength() { return length; }
-       int GetType() { return type; }
-       int GetDomain() { return domain; }
+       IPAddress(const std::string & s) {
+               if (s.find('\0') != std::string::npos) {
+                       throw std::runtime_error("Invalid IP address");
+               }
+               InitFromString(s.c_str());
+       }
+
+       const void* GetBinaryData() const { return &data; }
+       size_t GetBinaryLength() const { return length; }
+
+       void CopyBinaryData(void * dest) const {
+               memcpy(dest, GetBinaryData(), GetBinaryLength());
+       }
+
+       int GetType() const { return type; }
+       int GetDomain() const { return domain; }
        std::string & ToString();
        boost::shared_ptr<SocketAddress> NewSocketAddress(unsigned short int 
port);
 
+       static const IPAddress any4;
+       static const IPAddress any6;
 protected:
+       void InitFromString(const char * presentation);
+
        enum { BUFSIZE = 200 };
 
        std::string presentation;
@@ -49,6 +69,8 @@
                struct in_addr v4;
        } data;
        int type, domain, length;
+
+
 };
 
 #endif

Modified: trunk/udplog/srclib/Socket.cpp
===================================================================
--- trunk/udplog/srclib/Socket.cpp      2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/srclib/Socket.cpp      2011-10-26 04:49:14 UTC (rev 100788)
@@ -19,3 +19,35 @@
        }
 }
 
+int UDPSocket::JoinMulticast(const IPAddress & addr) {
+       int level, optname;
+       void *optval;
+       socklen_t optlen;
+       struct ip_mreqn mreq4;
+       struct ipv6_mreq mreq6;
+
+       if (addr.GetType() == AF_INET) {
+               addr.CopyBinaryData(&mreq4.imr_multiaddr.s_addr);
+               IPAddress::any4.CopyBinaryData(&mreq4.imr_address);
+               mreq4.imr_ifindex = 0;
+               level = IPPROTO_IP;
+               optname = IP_ADD_MEMBERSHIP;
+               optval = &mreq4;
+               optlen = sizeof(mreq4);
+       } else {
+               addr.CopyBinaryData(&mreq6.ipv6mr_multiaddr);
+               mreq6.ipv6mr_interface = 0;
+               level = IPPROTO_IPV6;
+               optname = IPV6_JOIN_GROUP;
+               optval = &mreq6;
+               optlen = sizeof(mreq6);
+       }
+
+       if (setsockopt(fd, level, optname, optval, optlen)) {
+               RaiseError("UDPSocket::JoinMulticast");
+               return errno;
+       } else {
+               return 0;
+       }
+}
+

Modified: trunk/udplog/srclib/Socket.h
===================================================================
--- trunk/udplog/srclib/Socket.h        2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/srclib/Socket.h        2011-10-26 04:49:14 UTC (rev 100788)
@@ -14,8 +14,14 @@
 // Do not instantiate this directly
 class Socket
 {
-public:
+private:
+       // Not default constructible
        Socket(){}
+
+       // Not copyable
+       Socket(const Socket & s) {}
+
+protected:
        Socket(int domain, int type, int protocol)
                : fd(-1) 
        {
@@ -28,6 +34,8 @@
                }
        }
 
+public:
+
        operator bool() {
                return good;
        }
@@ -62,22 +70,6 @@
                }
        }
 
-       int Mcast(const char* multicastAddr) { 
-               IPAddress any(INADDR_ANY);
-               struct ip_mreq imreq;
-
-               bzero(&imreq, sizeof(struct ip_mreq));
-               imreq.imr_multiaddr.s_addr = inet_addr(multicastAddr);
-               imreq.imr_interface.s_addr = INADDR_ANY;
-               if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void 
*)&imreq, 
-                                       sizeof(struct ip_mreq))) {
-                       RaiseError("Socket::Mcast");
-                       return errno;
-               } else {
-                       return 0;
-               }
-       }
-
        boost::shared_ptr<SocketAddress> GetPeerAddress() {
                if (connect(fd, SocketAddress::GetBuffer(), 
SocketAddress::GetBufferLength()) < 0) {
                        RaiseError("Socket::GetPeerAddress");
@@ -168,6 +160,11 @@
                        good = false;
                }
        }
+       
+       int JoinMulticast(const IPAddress & addr);
+private:
+       int JoinMulticast4(const IPAddress & addr);
+       int JoinMulticast6(const IPAddress & addr);
 };
 
 #endif

Modified: trunk/udplog/srclib/SocketAddress.h
===================================================================
--- trunk/udplog/srclib/SocketAddress.h 2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/srclib/SocketAddress.h 2011-10-26 04:49:14 UTC (rev 100788)
@@ -36,7 +36,7 @@
                data.v6.sin6_family = AF_INET6;
        }
 
-       SocketAddress(IPAddress & ip, unsigned short int port) 
+       SocketAddress(const IPAddress & ip, unsigned short int port) 
        {
                switch (ip.GetType()) {
                        case AF_INET:

Modified: trunk/udplog/udp2log/udp2log.cpp
===================================================================
--- trunk/udplog/udp2log/udp2log.cpp    2011-10-26 04:47:48 UTC (rev 100787)
+++ trunk/udplog/udp2log/udp2log.cpp    2011-10-26 04:49:14 UTC (rev 100788)
@@ -182,17 +182,22 @@
        signal(SIGPIPE, SIG_IGN);
 
        // Open the receiving socket
-       IPAddress any(INADDR_ANY);
-       SocketAddress saddr(any, (unsigned short int)port);
-       Socket socket;
-       socket = *(new UDPSocket());
+       SocketAddress saddr(IPAddress::any4, (unsigned short int)port);
+       UDPSocket socket;
        if (!socket) {
                cerr << "Unable to open socket\n";
                return 1;
        }
        socket.Bind(saddr);
-       if(strcmp("0", multicastAddr.c_str())){ //if multicast
-               socket.Mcast(multicastAddr.c_str());
+
+       // Join a multicast group if requested
+       if (multicastAddr != "0") {
+               try {
+                       socket.JoinMulticast(multicastAddr);
+               } catch (runtime_error & e) {
+                       cerr << "Error joining multicast group: " << e.what() 
<< endl;
+                       return 1;
+               }
        }
        // Process received packets
        boost::shared_ptr<SocketAddress> address;


_______________________________________________
MediaWiki-CVS mailing list
MediaWiki-CVS@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to