Skip to content

Commit

Permalink
IPv6
Browse files Browse the repository at this point in the history
  • Loading branch information
beef9999 committed Oct 13, 2023
1 parent 90b6abe commit b34804e
Show file tree
Hide file tree
Showing 13 changed files with 505 additions and 139 deletions.
18 changes: 17 additions & 1 deletion common/test/test_alog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ limitations under the License.
#include "../alog-functionptr.h"
#include "../alog-audit.h"
#include <gtest/gtest.h>
#include "photon/thread/thread.h"
#include <photon/thread/thread.h>
#include <photon/net/socket.h>
#include <chrono>
#include <vector>
#include <stdint.h>
Expand Down Expand Up @@ -556,6 +557,21 @@ TEST(ALog, LOG_LIMIT) {
EXPECT_LE(x, suppose + 3);
}

TEST(ALOG, IPAddr) {
log_output = &log_output_test;
DEFER(log_output = log_output_stdout);

photon::net::IPAddr ip("192.168.12.34");
EXPECT_STREQ(ip.to_string().c_str(), "192.168.12.34");
LOG_INFO(ip);
EXPECT_STREQ("192.168.12.34", log_output_test.log_start());

ip = photon::net::IPAddr("abcd:1111:222:33:4:5:6:7");
EXPECT_STREQ(ip.to_string().c_str(), "abcd:1111:222:33:4:5:6:7");
LOG_INFO(ip);
EXPECT_STREQ("abcd:1111:222:33:4:5:6:7", log_output_test.log_start());
}

int main(int argc, char **argv)
{
photon::vcpu_init();
Expand Down
10 changes: 5 additions & 5 deletions net/basic_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,11 +262,11 @@ bool ISocketStream::skip_read(size_t count) {
}

int do_get_name(int fd, Getter getter, EndPoint& addr) {
struct sockaddr_in addr_in;
socklen_t len = sizeof(addr_in);
int ret = getter(fd, (struct sockaddr*) &addr_in, &len);
if (ret < 0 || len != sizeof(addr_in)) return -1;
addr.from_sockaddr_in(addr_in);
sockaddr_storage storage(addr);
socklen_t len = storage.get_socklen();
int ret = getter(fd, storage.get_sockaddr(), &len);
if (ret < 0 || len > storage.get_socklen()) return -1;
addr = storage.to_endpoint();
return 0;
}

Expand Down
22 changes: 11 additions & 11 deletions net/datagram_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,23 +139,23 @@ class UDP : public DatagramSocketBase {
virtual int connect(const Addr* addr, size_t addr_len) override {
auto ep = (EndPoint*)addr;
assert(ep && addr_len == sizeof(*ep));
auto in = ep->to_sockaddr_in();
return do_connect((sockaddr*)&in, sizeof(in));
sockaddr_storage s(*ep);
return do_connect(s.get_sockaddr(), s.get_socklen());
}
virtual int bind(const Addr* addr, size_t addr_len) override {
auto ep = (EndPoint*)addr;
assert(ep && addr_len == sizeof(*ep));
auto in = ep->to_sockaddr_in();
return do_bind((sockaddr*)&in, sizeof(in));
sockaddr_storage s(*ep);
return do_bind(s.get_sockaddr(), s.get_socklen());
}
virtual ssize_t send(const struct iovec* iov, int iovcnt, const Addr* addr,
size_t addr_len, int flags = 0) override {
auto ep = (EndPoint*)addr;
if (likely(!ep) || unlikely(addr_len != sizeof(*ep)))
return do_send(iov, iovcnt, nullptr, 0, flags);
assert(addr_len == sizeof(*ep));
auto in = ep->to_sockaddr_in();
return do_send(iov, iovcnt, (sockaddr*)&in, sizeof(in), flags);
sockaddr_storage s(*ep);
return do_send(iov, iovcnt, s.get_sockaddr(), s.get_socklen(), flags);
}
virtual ssize_t recv(const struct iovec* iov, int iovcnt, Addr* addr,
size_t* addr_len, int flags) override {
Expand All @@ -164,12 +164,12 @@ class UDP : public DatagramSocketBase {
return do_recv(iov, iovcnt, nullptr, 0, flags);
}

sockaddr_in in;
size_t alen = sizeof(in);
auto ret = do_recv(iov, iovcnt, (sockaddr*)&in, &alen, flags);
sockaddr_storage s(*ep);
size_t alen = s.get_socklen();
auto ret = do_recv(iov, iovcnt, s.get_sockaddr(), &alen, flags);
if (ret >= 0) {
ep->from(in);
*addr_len = sizeof(*ep);
*ep = s.to_endpoint();
*addr_len = alen;
}
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion net/http/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ ISocketStream* PooledDialer::dial(std::string_view host, uint16_t port, bool sec
return sock;
}
LOG_DEBUG("connect ssl : ` ep : ` host : ` failed", secure, ep, host);
if (ipaddr.addr == 0) LOG_DEBUG("No connectable resolve result");
if (ipaddr.undefined()) LOG_DEBUG("No connectable resolve result");
// When failed, remove resolved result from dns cache so that following retries can try
// different ips.
resolver->discard_cache(strhost.c_str());
Expand Down
89 changes: 55 additions & 34 deletions net/kernel_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ limitations under the License.
#include <unordered_map>

#include <photon/common/alog.h>
#include <photon/common/alog-stdstring.h>
#include <photon/common/iovector.h>
#include <photon/io/fd-events.h>
#include <photon/thread/thread11.h>
Expand Down Expand Up @@ -60,20 +61,22 @@ limitations under the License.
#endif

LogBuffer& operator<<(LogBuffer& log, const in_addr& iaddr) {
return log << photon::net::IPAddr(ntohl(iaddr.s_addr));
return log << photon::net::IPAddr(iaddr);
}
LogBuffer& operator<<(LogBuffer& log, const in6_addr& iaddr) {
return log << photon::net::IPAddr(iaddr);
}

LogBuffer& operator<<(LogBuffer& log, const sockaddr_in& addr) {
return log << photon::net::EndPoint(addr);
photon::net::sockaddr_storage s(addr);
return log << s.to_endpoint();
}
LogBuffer& operator<<(LogBuffer& log, const sockaddr_in6& addr) {
photon::net::sockaddr_storage s(addr);
return log << s.to_endpoint();
}

LogBuffer& operator<<(LogBuffer& log, const sockaddr& addr) {
if (addr.sa_family == AF_INET) {
log << (const sockaddr_in&)addr;
} else {
log.printf("<sockaddr>");
}
return log;
photon::net::sockaddr_storage s(addr);
return log << s.to_endpoint();
}

namespace photon {
Expand All @@ -93,7 +96,7 @@ class KernelSocketStream : public SocketStreamBase {
} else {
fd = ::socket(socket_family, SOCK_STREAM, 0);
}
if (fd >= 0 && socket_family == AF_INET) {
if (fd >= 0 && (socket_family == AF_INET || socket_family == AF_INET6)) {
int val = 1;
::setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &val, (socklen_t) sizeof(val));
}
Expand Down Expand Up @@ -214,18 +217,16 @@ class KernelSocketClient : public SocketClientBase {
ISocketStream* connect(const char* path, size_t count) override {
struct sockaddr_un addr_un;
if (fill_uds_path(addr_un, path, count) != 0) return nullptr;
return do_connect((const sockaddr*) &addr_un, nullptr, sizeof(addr_un));
return do_connect((const sockaddr*) &addr_un, sizeof(addr_un));
}

ISocketStream* connect(EndPoint remote, EndPoint local = EndPoint()) override {
sockaddr_in addr_remote = remote.to_sockaddr_in();
auto r = (sockaddr*) &addr_remote;
if (local.empty()) {
return do_connect(r, nullptr, sizeof(addr_remote));
sockaddr_storage r(remote);
if (local.undefined()) {
return do_connect(r.get_sockaddr(), r.get_socklen());
}
sockaddr_in addr_local = local.to_sockaddr_in();
auto l = (sockaddr*) &addr_local;
return do_connect(r, l, sizeof(addr_remote));
sockaddr_storage l(local);
return do_connect(r.get_sockaddr(), r.get_socklen(), l.get_sockaddr(), l.get_socklen());
}

protected:
Expand All @@ -240,7 +241,8 @@ class KernelSocketClient : public SocketClientBase {
return net::connect(fd, remote, addrlen, m_timeout);
}

ISocketStream* do_connect(const sockaddr* remote, const sockaddr* local, socklen_t addrlen) {
ISocketStream* do_connect(const sockaddr* remote, socklen_t len_remote,
const sockaddr* local = nullptr, socklen_t len_local = 0) {
auto stream = create_stream();
std::unique_ptr<KernelSocketStream> ptr(stream);
if (!ptr || ptr->fd < 0) {
Expand All @@ -251,11 +253,11 @@ class KernelSocketClient : public SocketClientBase {
}
ptr->timeout(m_timeout);
if (local != nullptr) {
if (::bind(ptr->fd, local, addrlen) != 0) {
if (::bind(ptr->fd, local, len_local) != 0) {
LOG_ERRNO_RETURN(0, nullptr, "fail to bind socket");
}
}
auto ret = fd_connect(ptr->fd, remote, addrlen);
auto ret = fd_connect(ptr->fd, remote, len_remote);
if (ret < 0) {
LOG_ERRNO_RETURN(0, nullptr, "Failed to connect socket");
}
Expand Down Expand Up @@ -300,7 +302,7 @@ class KernelSocketServer : public SocketServerBase {
if (m_listen_fd < 0) {
LOG_ERRNO_RETURN(0, -1, "fail to setup listen fd");
}
if (m_socket_family == AF_INET) {
if (m_socket_family == AF_INET || m_socket_family == AF_INET6) {
if (setsockopt<int>(IPPROTO_TCP, TCP_NODELAY, 1) != 0) {
LOG_ERRNO_RETURN(EINVAL, -1, "failed to setsockopt of TCP_NODELAY");
}
Expand Down Expand Up @@ -336,8 +338,11 @@ class KernelSocketServer : public SocketServerBase {
}

int bind(uint16_t port, IPAddr addr) override {
auto addr_in = EndPoint(addr, port).to_sockaddr_in();
return ::bind(m_listen_fd, (struct sockaddr*)&addr_in, sizeof(addr_in));
if (m_socket_family == AF_INET6 && addr.undefined()) {
addr = IPAddr::V6Any();
}
sockaddr_storage s(EndPoint(addr, port));
return ::bind(m_listen_fd, s.get_sockaddr(), s.get_socklen());
}

int bind(const char* path, size_t count) override {
Expand Down Expand Up @@ -419,11 +424,13 @@ class KernelSocketServer : public SocketServerBase {
int do_accept() { return fd_accept(m_listen_fd, nullptr, nullptr); }

int do_accept(EndPoint& remote_endpoint) {
struct sockaddr_in addr_in;
socklen_t len = sizeof(addr_in);
int cfd = fd_accept(m_listen_fd, (struct sockaddr*) &addr_in, &len);
if (cfd < 0 || len != sizeof(addr_in)) return -1;
remote_endpoint.from_sockaddr_in(addr_in);
sockaddr_storage s(remote_endpoint);
socklen_t len = s.get_socklen();

int cfd = fd_accept(m_listen_fd, s.get_sockaddr(), &len);
if (cfd < 0 || len > s.get_socklen())
return -1;
remote_endpoint = s.to_endpoint();
return cfd;
}

Expand Down Expand Up @@ -900,7 +907,8 @@ class ETKernelSocketStream : public KernelSocketStream, public NotifyContext {
if (fd >= 0) etpoller.register_notifier(fd, this);
}

ETKernelSocketStream() : KernelSocketStream(AF_INET, true) {
ETKernelSocketStream(int socket_family, bool nonblocking) :
KernelSocketStream(socket_family, nonblocking) {
if (fd >= 0) etpoller.register_notifier(fd, this);
}

Expand Down Expand Up @@ -947,7 +955,7 @@ class ETKernelSocketClient : public KernelSocketClient {

protected:
KernelSocketStream* create_stream() override {
return new ETKernelSocketStream();
return new ETKernelSocketStream(m_socket_family, m_nonblocking);
}
};

Expand Down Expand Up @@ -981,19 +989,32 @@ class ETKernelSocketServer : public KernelSocketServer, public NotifyContext {
/* ET Socket - End */

LogBuffer& operator<<(LogBuffer& log, const IPAddr addr) {
return log.printf(addr.d, '.', addr.c, '.', addr.b, '.', addr.a);
if (addr.is_ipv4())
return log.printf(addr.a, '.', addr.b, '.', addr.c, '.', addr.d);
else {
return log.printf(addr.to_string());
}
}

LogBuffer& operator<<(LogBuffer& log, const EndPoint ep) {
return log << ep.addr << ':' << ep.port;
if (ep.is_ipv4())
return log << ep.addr << ':' << ep.port;
else
return log << '[' << ep.addr << "]:" << ep.port;
}

extern "C" ISocketClient* new_tcp_socket_client() {
return new KernelSocketClient(AF_INET, true);
}
extern "C" ISocketClient* new_tcp_socket_client_ipv6() {
return new KernelSocketClient(AF_INET6, true);
}
extern "C" ISocketServer* new_tcp_socket_server() {
return NewObj<KernelSocketServer>(AF_INET, false, true)->init();
}
extern "C" ISocketServer* new_tcp_socket_server_ipv6() {
return NewObj<KernelSocketServer>(AF_INET6, false, true)->init();
}
extern "C" ISocketClient* new_uds_client() {
return new KernelSocketClient(AF_UNIX, true);
}
Expand Down
Loading

0 comments on commit b34804e

Please sign in to comment.