Skip to content

Commit 02bbdbd

Browse files
committed
preliminary support of IPv6
1 parent f3adb2d commit 02bbdbd

File tree

15 files changed

+179
-81
lines changed

15 files changed

+179
-81
lines changed

contrib/hiredis/Hiredis.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ void Hiredis::handleWrite()
118118

119119
void Hiredis::logConnection(bool up) const
120120
{
121-
InetAddress localAddr = sockets::getLocalAddr(fd());
122-
InetAddress peerAddr = sockets::getPeerAddr(fd());
121+
InetAddress localAddr(sockets::getLocalAddr(fd()));
122+
InetAddress peerAddr(sockets::getPeerAddr(fd()));
123123

124124
LOG_INFO << localAddr.toIpPort() << " -> "
125125
<< peerAddr.toIpPort() << " is "

examples/protobuf/resolver/server.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ class ResolverServiceImpl : public ResolverService
5151

5252
{
5353
LOG_INFO << "ResolverServiceImpl::doneCallback " << host;
54-
int32_t ip = address.getSockAddrInet().sin_addr.s_addr;
54+
int32_t ip = address.ipNetEndian();
5555
if (ip)
5656
{
5757
response->set_resolved(true);
5858
response->add_ip(ip);
59-
response->add_port(address.getSockAddrInet().sin_port);
59+
response->add_port(address.portNetEndian());
6060
}
6161
else
6262
{

examples/roundtrip/roundtrip_udp.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ void serverReadCallback(int sockfd, muduo::Timestamp receiveTime)
3535
socklen_t addrLen = sizeof peerAddr;
3636
ssize_t nr = ::recvfrom(sockfd, message, sizeof message, 0, &peerAddr, &addrLen);
3737

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

4242
if (nr < 0)
@@ -118,7 +118,7 @@ void runClient(const char* ip, uint16_t port)
118118
{
119119
Socket sock(createNonblockingUDP());
120120
InetAddress serverAddr(ip, port);
121-
int ret = sockets::connect(sock.fd(), serverAddr.getSockAddrInet());
121+
int ret = sockets::connect(sock.fd(), serverAddr.getSockAddr());
122122
if (ret < 0)
123123
{
124124
LOG_SYSFATAL << "::connect";

muduo/net/Acceptor.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ using namespace muduo::net;
2525

2626
Acceptor::Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport)
2727
: loop_(loop),
28-
acceptSocket_(sockets::createNonblockingOrDie()),
28+
acceptSocket_(sockets::createNonblockingOrDie(listenAddr.family())),
2929
acceptChannel_(loop, acceptSocket_.fd()),
3030
listenning_(false),
3131
idleFd_(::open("/dev/null", O_RDONLY | O_CLOEXEC))

muduo/net/Connector.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ void Connector::stopInLoop()
7979

8080
void Connector::connect()
8181
{
82-
int sockfd = sockets::createNonblockingOrDie();
83-
int ret = sockets::connect(sockfd, serverAddr_.getSockAddrInet());
82+
int sockfd = sockets::createNonblockingOrDie(serverAddr_.family());
83+
int ret = sockets::connect(sockfd, serverAddr_.getSockAddr());
8484
int savedErrno = (ret == 0) ? 0 : errno;
8585
switch (savedErrno)
8686
{

muduo/net/InetAddress.cc

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,43 +37,82 @@ static const in_addr_t kInaddrLoopback = INADDR_LOOPBACK;
3737
// in_addr_t s_addr; /* address in network byte order */
3838
// };
3939

40+
// struct sockaddr_in6 {
41+
// sa_family_t sin6_family; /* address family: AF_INET6 */
42+
// uint16_t sin6_port; /* port in network byte order */
43+
// uint32_t sin6_flowinfo; /* IPv6 flow information */
44+
// struct in6_addr sin6_addr; /* IPv6 address */
45+
// uint32_t sin6_scope_id; /* IPv6 scope-id */
46+
// };
47+
4048
using namespace muduo;
4149
using namespace muduo::net;
4250

43-
BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in));
51+
BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in6));
52+
BOOST_STATIC_ASSERT(offsetof(sockaddr_in, sin_family) == 0);
53+
BOOST_STATIC_ASSERT(offsetof(sockaddr_in6, sin6_family) == 0);
54+
BOOST_STATIC_ASSERT(offsetof(sockaddr_in, sin_port) == 2);
55+
BOOST_STATIC_ASSERT(offsetof(sockaddr_in6, sin6_port) == 2);
4456

45-
InetAddress::InetAddress(uint16_t port, bool loopbackOnly)
57+
InetAddress::InetAddress(uint16_t port, bool loopbackOnly, bool ipv6)
4658
{
47-
bzero(&addr_, sizeof addr_);
48-
addr_.sin_family = AF_INET;
49-
in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
50-
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
51-
addr_.sin_port = sockets::hostToNetwork16(port);
59+
BOOST_STATIC_ASSERT(offsetof(InetAddress, addr6_) == 0);
60+
BOOST_STATIC_ASSERT(offsetof(InetAddress, addr_) == 0);
61+
if (ipv6)
62+
{
63+
bzero(&addr6_, sizeof addr6_);
64+
addr6_.sin6_family = AF_INET6;
65+
in6_addr ip = loopbackOnly ? in6addr_loopback : in6addr_any;
66+
addr6_.sin6_addr = ip;
67+
addr6_.sin6_port = sockets::hostToNetwork16(port);
68+
}
69+
else
70+
{
71+
bzero(&addr_, sizeof addr_);
72+
addr_.sin_family = AF_INET;
73+
in_addr_t ip = loopbackOnly ? kInaddrLoopback : kInaddrAny;
74+
addr_.sin_addr.s_addr = sockets::hostToNetwork32(ip);
75+
addr_.sin_port = sockets::hostToNetwork16(port);
76+
}
5277
}
5378

54-
InetAddress::InetAddress(StringArg ip, uint16_t port)
79+
InetAddress::InetAddress(StringArg ip, uint16_t port, bool ipv6)
5580
{
56-
bzero(&addr_, sizeof addr_);
57-
sockets::fromIpPort(ip.c_str(), port, &addr_);
81+
if (ipv6)
82+
{
83+
bzero(&addr6_, sizeof addr6_);
84+
sockets::fromIpPort(ip.c_str(), port, &addr6_);
85+
}
86+
else
87+
{
88+
bzero(&addr_, sizeof addr_);
89+
sockets::fromIpPort(ip.c_str(), port, &addr_);
90+
}
5891
}
5992

6093
string InetAddress::toIpPort() const
6194
{
62-
char buf[32];
63-
sockets::toIpPort(buf, sizeof buf, addr_);
95+
char buf[64] = "";
96+
sockets::toIpPort(buf, sizeof buf, getSockAddr());
6497
return buf;
6598
}
6699

67100
string InetAddress::toIp() const
68101
{
69-
char buf[32];
70-
sockets::toIp(buf, sizeof buf, addr_);
102+
char buf[64] = "";
103+
sockets::toIp(buf, sizeof buf, getSockAddr());
71104
return buf;
72105
}
73106

107+
uint32_t InetAddress::ipNetEndian() const
108+
{
109+
assert(family() == AF_INET);
110+
return addr_.sin_addr.s_addr;
111+
}
112+
74113
uint16_t InetAddress::toPort() const
75114
{
76-
return sockets::networkToHost16(addr_.sin_port);
115+
return sockets::networkToHost16(portNetEndian());
77116
}
78117

79118
static __thread char t_resolveBuffer[64 * 1024];

muduo/net/InetAddress.h

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ namespace muduo
2020
{
2121
namespace net
2222
{
23+
namespace sockets
24+
{
25+
const struct sockaddr* sockaddr_cast(const struct sockaddr_in6* addr);
26+
}
2327

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

3539
/// Constructs an endpoint with given ip and port.
3640
/// @c ip should be "1.2.3.4"
37-
InetAddress(StringArg ip, uint16_t port);
41+
InetAddress(StringArg ip, uint16_t port, bool ipv6 = false);
3842

3943
/// Constructs an endpoint with given struct @c sockaddr_in
4044
/// Mostly used when accepting new connections
41-
InetAddress(const struct sockaddr_in& addr)
45+
explicit InetAddress(const struct sockaddr_in& addr)
4246
: addr_(addr)
4347
{ }
4448

49+
explicit InetAddress(const struct sockaddr_in6& addr)
50+
: addr6_(addr)
51+
{ }
52+
53+
sa_family_t family() const { return addr_.sin_family; }
4554
string toIp() const;
4655
string toIpPort() const;
4756
uint16_t toPort() const;
4857

4958
// default copy/assignment are Okay
5059

51-
const struct sockaddr_in& getSockAddrInet() const { return addr_; }
52-
void setSockAddrInet(const struct sockaddr_in& addr) { addr_ = addr; }
60+
const struct sockaddr* getSockAddr() const { return sockets::sockaddr_cast(&addr6_); }
61+
void setSockAddrInet6(const struct sockaddr_in6& addr6) { addr6_ = addr6; }
5362

54-
uint32_t ipNetEndian() const { return addr_.sin_addr.s_addr; }
63+
uint32_t ipNetEndian() const;
5564
uint16_t portNetEndian() const { return addr_.sin_port; }
5665

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

6372
private:
64-
struct sockaddr_in addr_;
73+
union
74+
{
75+
struct sockaddr_in addr_;
76+
struct sockaddr_in6 addr6_;
77+
};
6578
};
6679

6780
}

muduo/net/Socket.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ bool Socket::getTcpInfoString(char* buf, int len) const
6060

6161
void Socket::bindAddress(const InetAddress& addr)
6262
{
63-
sockets::bindOrDie(sockfd_, addr.getSockAddrInet());
63+
sockets::bindOrDie(sockfd_, addr.getSockAddr());
6464
}
6565

6666
void Socket::listen()
@@ -70,12 +70,12 @@ void Socket::listen()
7070

7171
int Socket::accept(InetAddress* peeraddr)
7272
{
73-
struct sockaddr_in addr;
73+
struct sockaddr_in6 addr;
7474
bzero(&addr, sizeof addr);
7575
int connfd = sockets::accept(sockfd_, &addr);
7676
if (connfd >= 0)
7777
{
78-
peeraddr->setSockAddrInet(addr);
78+
peeraddr->setSockAddrInet6(addr);
7979
}
8080
return connfd;
8181
}

0 commit comments

Comments
 (0)