Skip to content

Commit

Permalink
preliminary support of IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
chenshuo committed Nov 13, 2015
1 parent f3adb2d commit 02bbdbd
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 81 deletions.
4 changes: 2 additions & 2 deletions contrib/hiredis/Hiredis.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ void Hiredis::handleWrite()

void Hiredis::logConnection(bool up) const
{
InetAddress localAddr = sockets::getLocalAddr(fd());
InetAddress peerAddr = sockets::getPeerAddr(fd());
InetAddress localAddr(sockets::getLocalAddr(fd()));
InetAddress peerAddr(sockets::getPeerAddr(fd()));

LOG_INFO << localAddr.toIpPort() << " -> "
<< peerAddr.toIpPort() << " is "
Expand Down
4 changes: 2 additions & 2 deletions examples/protobuf/resolver/server.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ class ResolverServiceImpl : public ResolverService

{
LOG_INFO << "ResolverServiceImpl::doneCallback " << host;
int32_t ip = address.getSockAddrInet().sin_addr.s_addr;
int32_t ip = address.ipNetEndian();
if (ip)
{
response->set_resolved(true);
response->add_ip(ip);
response->add_port(address.getSockAddrInet().sin_port);
response->add_port(address.portNetEndian());
}
else
{
Expand Down
6 changes: 3 additions & 3 deletions examples/roundtrip/roundtrip_udp.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ void serverReadCallback(int sockfd, muduo::Timestamp receiveTime)
socklen_t addrLen = sizeof peerAddr;
ssize_t nr = ::recvfrom(sockfd, message, sizeof message, 0, &peerAddr, &addrLen);

char addrStr[32];
sockets::toIpPort(addrStr, sizeof addrStr, *reinterpret_cast<struct sockaddr_in*>(&peerAddr));
char addrStr[64];
sockets::toIpPort(addrStr, sizeof addrStr, &peerAddr);
LOG_DEBUG << "received " << nr << " bytes from " << addrStr;

if (nr < 0)
Expand Down Expand Up @@ -118,7 +118,7 @@ void runClient(const char* ip, uint16_t port)
{
Socket sock(createNonblockingUDP());
InetAddress serverAddr(ip, port);
int ret = sockets::connect(sock.fd(), serverAddr.getSockAddrInet());
int ret = sockets::connect(sock.fd(), serverAddr.getSockAddr());
if (ret < 0)
{
LOG_SYSFATAL << "::connect";
Expand Down
2 changes: 1 addition & 1 deletion muduo/net/Acceptor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ using namespace muduo::net;

Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport)
: loop_(loop),
acceptSocket_(sockets::createNonblockingOrDie()),
acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),
acceptChannel_(loop, acceptSocket_.fd()),
listenning_(false),
idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC))
Expand Down
4 changes: 2 additions & 2 deletions muduo/net/Connector.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ void Connector::stopInLoop()

void Connector::connect()
{
int sockfd = sockets::createNonblockingOrDie();
int ret = sockets::connect(sockfd, serverAddr_.getSockAddrInet());
int sockfd = sockets::createNonblockingOrDie(serverAddr_.family());
int ret = sockets::connect(sockfd, serverAddr_.getSockAddr());
int savedErrno = (ret == 0) ? 0 : errno;
switch (savedErrno)
{
Expand Down
69 changes: 54 additions & 15 deletions muduo/net/InetAddress.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,43 +37,82 @@ static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
// in_addr_t s_addr; /* address in network byte order */
// };

// struct sockaddr_in6 {
// sa_family_t sin6_family; /* address family: AF_INET6 */
// uint16_t sin6_port; /* port in network byte order */
// uint32_t sin6_flowinfo; /* IPv6 flow information */
// struct in6_addr sin6_addr; /* IPv6 address */
// uint32_t sin6_scope_id; /* IPv6 scope-id */
// };

using namespace muduo;
using namespace muduo::net;

BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in));
BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in6));
BOOST_STATIC_ASSERT(offsetof(sockaddr_in, sin_family) == 0);
BOOST_STATIC_ASSERT(offsetof(sockaddr_in6, sin6_family) == 0);
BOOST_STATIC_ASSERT(offsetof(sockaddr_in, sin_port) == 2);
BOOST_STATIC_ASSERT(offsetof(sockaddr_in6, sin6_port) == 2);

InetAddress::InetAddress(uint16_t port, bool loopbackOnly)
InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6)
{
bzero(&addr_, sizeof addr_);
addr_.sin_family = AF_INET;
in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
addr_.sin_port = sockets::hostToNetwork16(port);
BOOST_STATIC_ASSERT(offsetof(InetAddress, addr6_) == 0);
BOOST_STATIC_ASSERT(offsetof(InetAddress, addr_) == 0);
if (ipv6)
{
bzero(&addr6_, sizeof addr6_);
addr6_.sin6_family = AF_INET6;
in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any;
addr6_.sin6_addr = ip;
addr6_.sin6_port = sockets::hostToNetwork16(port);
}
else
{
bzero(&addr_, sizeof addr_);
addr_.sin_family = AF_INET;
in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
addr_.sin_port = sockets::hostToNetwork16(port);
}
}

InetAddress::InetAddress(StringArg ip, uint16_t port)
InetAddress::InetAddress(StringArg ip, uint16_t port, bool ipv6)
{
bzero(&addr_, sizeof addr_);
sockets::fromIpPort(ip.c_str(), port, &addr_);
if (ipv6)
{
bzero(&addr6_, sizeof addr6_);
sockets::fromIpPort(ip.c_str(), port, &addr6_);
}
else
{
bzero(&addr_, sizeof addr_);
sockets::fromIpPort(ip.c_str(), port, &addr_);
}
}

string InetAddress::toIpPort() const
{
char buf[32];
sockets::toIpPort(buf, sizeof buf, addr_);
char buf[64] = "";
sockets::toIpPort(buf, sizeof buf, getSockAddr());
return buf;
}

string InetAddress::toIp() const
{
char buf[32];
sockets::toIp(buf, sizeof buf, addr_);
char buf[64] = "";
sockets::toIp(buf, sizeof buf, getSockAddr());
return buf;
}

uint32_t InetAddress::ipNetEndian() const
{
assert(family() == AF_INET);
return addr_.sin_addr.s_addr;
}

uint16_t InetAddress::toPort() const
{
return sockets::networkToHost16(addr_.sin_port);
return sockets::networkToHost16(portNetEndian());
}

static __thread char t_resolveBuffer[64 * 1024];
Expand Down
27 changes: 20 additions & 7 deletions muduo/net/InetAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ namespace muduo
{
namespace net
{
namespace sockets
{
const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr);
}

///
/// Wrapper of sockaddr_in.
Expand All @@ -30,28 +34,33 @@ class InetAddress : public muduo::copyable
public:
/// Constructs an endpoint with given port number.
/// Mostly used in TcpServer listening.
explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false);
explicit InetAddress(uint16_t port = 0, bool loopbackOnly = false, bool ipv6 = false);

/// Constructs an endpoint with given ip and port.
/// @c ip should be "1.2.3.4"
InetAddress(StringArg ip, uint16_t port);
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);

/// Constructs an endpoint with given struct @c sockaddr_in
/// Mostly used when accepting new connections
InetAddress(const struct sockaddr_in& addr)
explicit InetAddress(const struct sockaddr_in& addr)
: addr_(addr)
{ }

explicit InetAddress(const struct sockaddr_in6& addr)
: addr6_(addr)
{ }

sa_family_t family() const { return addr_.sin_family; }
string toIp() const;
string toIpPort() const;
uint16_t toPort() const;

// default copy/assignment are Okay

const struct sockaddr_in& getSockAddrInet() const { return addr_; }
void setSockAddrInet(const struct sockaddr_in& addr) { addr_ = addr; }
const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast(&addr6_); }
void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; }

uint32_t ipNetEndian() const { return addr_.sin_addr.s_addr; }
uint32_t ipNetEndian() const;
uint16_t portNetEndian() const { return addr_.sin_port; }

// resolve hostname to IP address, not changing port or sin_family
Expand All @@ -61,7 +70,11 @@ class InetAddress : public muduo::copyable
// static std::vector<InetAddress> resolveAll(const char* hostname, uint16_t port = 0);

private:
struct sockaddr_in addr_;
union
{
struct sockaddr_in addr_;
struct sockaddr_in6 addr6_;
};
};

}
Expand Down
6 changes: 3 additions & 3 deletions muduo/net/Socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ bool Socket::getTcpInfoString(char* buf, int len) const

void Socket::bindAddress(const InetAddress& addr)
{
sockets::bindOrDie(sockfd_, addr.getSockAddrInet());
sockets::bindOrDie(sockfd_, addr.getSockAddr());
}

void Socket::listen()
Expand All @@ -70,12 +70,12 @@ void Socket::listen()

int Socket::accept(InetAddress* peeraddr)
{
struct sockaddr_in addr;
struct sockaddr_in6 addr;
bzero(&addr, sizeof addr);
int connfd = sockets::accept(sockfd_, &addr);
if (connfd >= 0)
{
peeraddr->setSockAddrInet(addr);
peeraddr->setSockAddrInet6(addr);
}
return connfd;
}
Expand Down
Loading

0 comments on commit 02bbdbd

Please sign in to comment.