Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipv6 #192

Merged
merged 2 commits into from
Oct 23, 2023
Merged

ipv6 #192

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -DNDEBUG -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-O3 -g") # Only for CI test
set(CMAKE_CXX_FLAGS_MINSIZEREL "-O2 -g") # Only for CI test
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Expand Down
19 changes: 18 additions & 1 deletion common/test/test_alog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ 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 <photon/net/utils-stdstring.h>
#include <chrono>
#include <vector>
#include <stdint.h>
Expand Down Expand Up @@ -556,6 +558,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(photon::net::to_string(ip).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(photon::net::to_string(ip).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
1 change: 1 addition & 0 deletions include/photon/net/utils-stdstring.h
59 changes: 59 additions & 0 deletions net/base_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ limitations under the License.
Internal header provides abstract socket base class
***/

#include <netinet/in.h>
#include <vector>

#include <photon/net/socket.h>
Expand All @@ -37,6 +38,64 @@ Internal header provides abstract socket base class
namespace photon {
namespace net {

// sockaddr_storage is the container for any socket address type
struct sockaddr_storage {
sockaddr_storage() = default;
explicit sockaddr_storage(const EndPoint& ep) {
if (ep.is_ipv4()) {
auto* in4 = (sockaddr_in*) &store;
in4->sin_family = AF_INET;
in4->sin_port = htons(ep.port);
in4->sin_addr.s_addr = ep.addr.to_nl();
} else {
auto* in6 = (sockaddr_in6*) &store;
in6->sin6_family = AF_INET6;
in6->sin6_port = htons(ep.port);
in6->sin6_addr = ep.addr.addr;
}
}
explicit sockaddr_storage(const sockaddr_in& addr) {
*((sockaddr_in*) &store) = addr;
}
explicit sockaddr_storage(const sockaddr_in6& addr) {
*((sockaddr_in6*) &store) = addr;
}
explicit sockaddr_storage(const sockaddr& addr) {
*((sockaddr*) &store) = addr;
}
EndPoint to_endpoint() const {
EndPoint ep;
if (store.ss_family == AF_INET6) {
auto s6 = (sockaddr_in6*) &store;
ep.addr = IPAddr(s6->sin6_addr);
ep.port = ntohs(s6->sin6_port);
} else if (store.ss_family == AF_INET) {
auto s4 = (sockaddr_in*) &store;
ep.addr = IPAddr(s4->sin_addr);
ep.port = ntohs(s4->sin_port);
}
return ep;
}
sockaddr* get_sockaddr() const {
return (sockaddr*) &store;
}
socklen_t get_socklen() const {
switch (store.ss_family) {
case AF_INET:
return sizeof(sockaddr_in);
case AF_INET6:
return sizeof(sockaddr_in6);
default:
return 0;
}
}
socklen_t get_max_socklen() const {
return sizeof(store);
}
// store must be zero initialized
::sockaddr_storage store = {};
};

struct SocketOpt {
int level;
int opt_name;
Expand Down
11 changes: 6 additions & 5 deletions net/basic_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ limitations under the License.
#include <photon/common/alog.h>
#include <photon/common/iovector.h>
#include <photon/common/utility.h>
#include "base_socket.h"

#ifndef MSG_ZEROCOPY
#define MSG_ZEROCOPY 0x4000000
Expand Down Expand Up @@ -262,11 +263,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;
socklen_t len = storage.get_max_socklen();
int ret = getter(fd, storage.get_sockaddr(), &len);
if (ret < 0 || len > storage.get_max_socklen()) return -1;
addr = storage.to_endpoint();
return 0;
}

Expand Down
29 changes: 15 additions & 14 deletions net/datagram_socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ limitations under the License.

#include "datagram_socket.h"

#include <sys/fcntl.h>
#include <sys/un.h>
#include <unistd.h>
#include <photon/common/alog.h>
#include <photon/common/utility.h>
#include <photon/io/fd-events.h>
#include <photon/net/basic_socket.h>
#include <photon/net/socket.h>
#include <sys/fcntl.h>
#include <sys/un.h>
#include <unistd.h>
#include "base_socket.h"

namespace photon {
namespace net {
Expand Down Expand Up @@ -139,23 +140,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 +165,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
16 changes: 9 additions & 7 deletions net/http/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ class PooledDialer {
std::unique_ptr<Resolver> resolver;

//etsocket seems not support multi thread very well, use tcp_socket now. need to find out why
PooledDialer() :
explicit PooledDialer(bool ipv6) :
tls_ctx(new_tls_context(nullptr, nullptr, nullptr)),
tcpsock(new_tcp_socket_pool(new_tcp_socket_client(), -1, true)),
tlssock(new_tcp_socket_pool(new_tls_client(tls_ctx, new_tcp_socket_client(), true), -1, true)),
resolver(new_default_resolver(kDNSCacheLife)) {
auto tcp_cli = ipv6 ? new_tcp_socket_client_ipv6() : new_tcp_socket_client();
auto tls_cli = ipv6 ? new_tcp_socket_client_ipv6() : new_tcp_socket_client();
tcpsock.reset(new_tcp_socket_pool(tcp_cli, -1, true));
tlssock.reset(new_tcp_socket_pool(new_tls_client(tls_ctx, tls_cli, true), -1, true));
}

~PooledDialer() { delete tls_ctx; }
Expand Down Expand Up @@ -77,7 +79,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 Expand Up @@ -107,8 +109,8 @@ class ClientImpl : public Client {
PooledDialer m_dialer;
CommonHeaders<> m_common_headers;
ICookieJar *m_cookie_jar;
ClientImpl(ICookieJar *cookie_jar) :
m_cookie_jar(cookie_jar) {}
ClientImpl(ICookieJar *cookie_jar, bool ipv6) :
m_dialer(ipv6), m_cookie_jar(cookie_jar) {}

using SocketStream_ptr = std::unique_ptr<ISocketStream>;
int redirect(Operation* op) {
Expand Down Expand Up @@ -258,7 +260,7 @@ class ClientImpl : public Client {
}
};

Client* new_http_client(ICookieJar *cookie_jar) { return new ClientImpl(cookie_jar); }
Client* new_http_client(ICookieJar *cookie_jar, bool ipv6) { return new ClientImpl(cookie_jar, ipv6); }

} // namespace http
} // namespace net
Expand Down
2 changes: 1 addition & 1 deletion net/http/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class Client : public Object {
};

//A Client without cookie_jar would ignore all response-header "Set-Cookies"
Client* new_http_client(ICookieJar *cookie_jar = nullptr);
Client* new_http_client(ICookieJar *cookie_jar = nullptr, bool ipv6 = false);

ICookieJar* new_simple_cookie_jar();

Expand Down
Loading