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

[WIP]feat: support ipv6 #100

Open
wants to merge 42 commits into
base: unstable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
6f59c35
feat: support ipv6
marsevilspirit Nov 29, 2024
640b6e1
update
marsevilspirit Nov 29, 2024
437dbcc
update
marsevilspirit Nov 29, 2024
c07bb77
update
marsevilspirit Nov 29, 2024
0b64a3d
Improve code quality
marsevilspirit Nov 29, 2024
73b2e1a
fix blank
marsevilspirit Nov 29, 2024
818e5ac
Improve code quality
marsevilspirit Nov 29, 2024
0f26214
add blank
marsevilspirit Nov 30, 2024
c5128c1
support ipv4 and ipv6
marsevilspirit Dec 1, 2024
5ee3235
add listen sockets manager
marsevilspirit Dec 1, 2024
d7ffa9b
use vector
marsevilspirit Dec 2, 2024
945a88e
update
marsevilspirit Dec 2, 2024
35e553a
support kqueue listensockets
marsevilspirit Dec 3, 2024
c02cbf8
Improve code quality
marsevilspirit Dec 3, 2024
120cc3f
support conf
marsevilspirit Dec 3, 2024
c928b1b
delete debug info
marsevilspirit Dec 3, 2024
6cabd52
update
marsevilspirit Dec 4, 2024
fc2c06f
clang format
marsevilspirit Dec 4, 2024
1ae6c08
clang format
marsevilspirit Dec 4, 2024
7d448ef
clang format
marsevilspirit Dec 4, 2024
3b56a5a
update
marsevilspirit Dec 4, 2024
2c422e1
update
marsevilspirit Dec 4, 2024
a066ce0
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Dec 7, 2024
fb55368
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Dec 12, 2024
0246161
rename
marsevilspirit Dec 12, 2024
0fc8851
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Dec 14, 2024
198de69
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Dec 28, 2024
04ad524
update
marsevilspirit Dec 29, 2024
288e6e5
fix conf bug
marsevilspirit Dec 30, 2024
9d485d4
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Dec 30, 2024
3350a78
update
marsevilspirit Dec 30, 2024
a7d01e6
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Jan 6, 2025
ebd0907
make format
marsevilspirit Jan 6, 2025
3868f52
fix kqueue kevent
marsevilspirit Jan 6, 2025
2aada3b
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Jan 15, 2025
f0e0fe1
fix kqueue bugs
marsevilspirit Jan 15, 2025
886a3d4
update
marsevilspirit Jan 16, 2025
f27731b
format
marsevilspirit Jan 16, 2025
c7e0f35
format
marsevilspirit Jan 16, 2025
b4f8d9b
update
marsevilspirit Jan 16, 2025
762f95a
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Jan 18, 2025
73442c1
Merge branch 'unstable' into feat-support-ipv6
marsevilspirit Jan 20, 2025
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 etc/conf/kiwi.conf
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,4 @@ rocksdb-periodic-second 259200;
############################### RAFT ###############################
use-raft no
# Braft relies on brpc to communicate via the default port number plus the port offset
raft-port-offset 10
raft-port-offset 10
18 changes: 17 additions & 1 deletion src/net/base_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@

namespace net {

int BaseSocket::CreateTCPSocket() { return ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); }
int BaseSocket::CreateTCPSocket(const SocketAddr &addr) {
if (addr.IsIpv4()) {
return ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
} else {
return ::socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
}
}


int BaseSocket::CreateUDPSocket() { return ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); }

Expand Down Expand Up @@ -87,6 +94,15 @@ bool BaseSocket::SetReusePort() {
return false;
}

bool BaseSocket::SetDisableIpv6Only() {
int ipv6only = 0;
if (::setsockopt(Fd(), IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&ipv6only), sizeof(ipv6only)) == -1) {
WARN("SetIpv6Only fd:{} error:{}", Fd(), errno);
return false;
}
return true;
}

bool BaseSocket::GetLocalAddr(SocketAddr &addr) {
sockaddr_in localAddr{};
socklen_t len = sizeof(localAddr);
Expand Down
10 changes: 4 additions & 6 deletions src/net/base_socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@

#include <sys/socket.h>

#include <functional>
#include <string>

#include "base_event.h"
#include "net_event.h"
#include "socket_addr.h"

Expand All @@ -34,11 +30,11 @@ class BaseSocket : public NetEvent {

~BaseSocket() override = default;

void OnError() override{};
void OnError() override {};

void Close() override;

static int CreateTCPSocket();
static int CreateTCPSocket(const SocketAddr &addr);

static int CreateUDPSocket();

Expand All @@ -57,6 +53,8 @@ class BaseSocket : public NetEvent {

bool SetReusePort();

bool SetDisableIpv6Only();

bool GetLocalAddr(SocketAddr &);

bool GetPeerAddr(SocketAddr &);
Expand Down
2 changes: 1 addition & 1 deletion src/net/callback_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class NetEvent;

// Auxiliary structure
struct Connection {
explicit Connection(std::unique_ptr<NetEvent> netEvent) : netEvent_(std::move(netEvent)), addr_(0, 0) {}
explicit Connection(std::unique_ptr<NetEvent> netEvent) : netEvent_(std::move(netEvent)) {}

~Connection() = default;

Expand Down
5 changes: 3 additions & 2 deletions src/net/client_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@

#include <sstream>

#include <sys/socket.h>
#include "client_socket.h"

namespace net {

bool ClientSocket::Connect() {
fd_ = CreateTCPSocket();
fd_ = CreateTCPSocket(addr_);
if (fd_ == -1) {
onConnectFail_("CreateTCPSocket open socket failed");
return false;
Expand All @@ -22,7 +23,7 @@ bool ClientSocket::Connect() {
SetRcvBuf();
SetSndBuf();

auto ret = connect(Fd(), (sockaddr*)&addr_.GetAddr(), sizeof(sockaddr_in));
int ret = connect(Fd(), addr_.GetAddr(), addr_.GetAddrLen());
if (0 != ret) {
if (EINPROGRESS == errno) {
return true;
Expand Down
13 changes: 8 additions & 5 deletions src/net/listen_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include <netinet/tcp.h>
#include <sys/socket.h>

#include "config.h"
#include "listen_socket.h"
Expand All @@ -19,7 +20,7 @@ const int ListenSocket::LISTENQ = 1024;
bool ListenSocket::REUSE_PORT = true;

int ListenSocket::OnReadable(const std::shared_ptr<Connection> &conn, std::string *readBuff) {
struct sockaddr_in clientAddr {};
struct sockaddr_in clientAddr{};
auto newConnFd = Accept(&clientAddr);
if (newConnFd == 0) {
ERROR("ListenSocket fd:{},Accept error:{}", Fd(), errno);
Expand Down Expand Up @@ -68,7 +69,7 @@ bool ListenSocket::Open() {
}

if (SocketType() == SOCKET_LISTEN_TCP) {
fd_ = CreateTCPSocket();
fd_ = CreateTCPSocket(addr_);
} else if (SocketType() == SOCKET_LISTEN_UDP) {
fd_ = CreateUDPSocket();
} else {
Expand All @@ -88,15 +89,17 @@ bool ListenSocket::Bind() {
if (!SetReusePort()) {
REUSE_PORT = false;
}
if (addr_.IsIpv6()) {
SetDisableIpv6Only();
}

struct sockaddr_in serv = addr_.GetAddr();

int ret = ::bind(Fd(), reinterpret_cast<struct sockaddr *>(&serv), sizeof serv);
int ret = ::bind(Fd(), addr_.GetAddr(), addr_.GetAddrLen());
if (0 != ret) {
ERROR("ListenSocket fd:{},Bind error:{}", Fd(), errno);
Close();
return false;
}

return true;
}

Expand Down
107 changes: 84 additions & 23 deletions src/net/socket_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,118 @@ namespace net {
struct SocketAddr {
SocketAddr() { Clear(); }

SocketAddr(const SocketAddr &other) { memcpy(&addr_, &other.addr_, sizeof addr_); }
SocketAddr(const SocketAddr &other) { memcpy(&addr_, &other.addr_, sizeof(addr_)); }

SocketAddr &operator=(const SocketAddr &other) {
if (this != &other) {
memcpy(&addr_, &other.addr_, sizeof addr_);
memcpy(&addr_, &other.addr_, sizeof(addr_));
}
return *this;
}

explicit SocketAddr(const sockaddr_in &addr) { Init(addr); }

SocketAddr(uint32_t netip, uint16_t netport) { Init(netip, netport); }
explicit SocketAddr(const sockaddr_in6 &addr) { Init(addr); }

SocketAddr(const std::string &ip, uint16_t hostport) { Init(ip, hostport); }

void Init(const sockaddr_in &addr) { memcpy(&addr_, &addr, sizeof(addr)); }

void Init(uint32_t netIp, uint16_t netPort) {
addr_.sin_family = AF_INET;
addr_.sin_addr.s_addr = netIp;
addr_.sin_port = netPort;
}
void Init(const sockaddr_in6 &addr) { memcpy(&addr_, &addr, sizeof(addr)); }

void Init(const std::string &ip, uint16_t hostPort) {
addr_.sin_family = AF_INET;
addr_.sin_addr.s_addr = ::inet_addr(ip.data());
addr_.sin_port = htons(hostPort);
if (::inet_pton(AF_INET, ip.c_str(), &addr_.addr4_.sin_addr) == 1) {
addr_.addr4_.sin_family = AF_INET;
addr_.addr4_.sin_port = htons(hostPort);
} else if (::inet_pton(AF_INET6, ip.c_str(), &addr_.addr6_.sin6_addr) == 1) {
addr_.addr6_.sin6_family = AF_INET6;
addr_.addr6_.sin6_port = htons(hostPort);
}
}

const sockaddr *GetAddr() const {
if (IsIpv4()) {
marsevilspirit marked this conversation as resolved.
Show resolved Hide resolved
return reinterpret_cast<const sockaddr *>(&addr_.addr4_);
} else if (IsIpv6()) {
return reinterpret_cast<const sockaddr *>(&addr_.addr6_);
}
return nullptr;
}

const sockaddr_in &GetAddr() const { return addr_; }
socklen_t GetAddrLen() const {
if (IsIpv4()) {
return sizeof(addr_.addr4_);
} else if (IsIpv6()) {
return sizeof(addr_.addr6_);
}
return 0;
}

std::string GetIP() const {
if (IsIpv4()) {
char ipv4_buf[INET_ADDRSTRLEN] = {0};
if (::inet_ntop(AF_INET, &addr_.addr4_.sin_addr, ipv4_buf, sizeof(ipv4_buf))) {
return ipv4_buf;
}
} else if (IsIpv6()) {
char ipv6_buf[INET6_ADDRSTRLEN] = {0};
if (::inet_ntop(AF_INET6, &addr_.addr6_.sin6_addr, ipv6_buf, sizeof(ipv6_buf))) {
return ipv6_buf;
}
}
return {};
}

inline std::string GetIP() const { return ::inet_ntoa(addr_.sin_addr); }
std::string GetIP(char *buf, socklen_t size) const {
if (IsIpv4()) {
if (::inet_ntop(AF_INET, &addr_.addr4_.sin_addr, buf, size)) {
return buf;
}
} else if (IsIpv6()) {
if (::inet_ntop(AF_INET6, &addr_.addr6_.sin6_addr, buf, size)) {
return buf;
}
}
return {};
}

inline std::string GetIP(char *buf, socklen_t size) const {
return ::inet_ntop(AF_INET, reinterpret_cast<const char *>(&addr_.sin_addr), buf, size);
uint16_t GetPort() const {
if (IsIpv4()) {
return ntohs(addr_.addr4_.sin_port);
} else if (IsIpv6()) {
return ntohs(addr_.addr6_.sin6_port);
}
return 0;
}

inline uint16_t GetPort() const { return ntohs(addr_.sin_port); }
bool IsValid() const { return addr_.addr4_.sin_family != 0 || addr_.addr6_.sin6_family != 0; }

bool IsIpv6() const { return addr_.addr6_.sin6_family == AF_INET6; }
AlexStocks marked this conversation as resolved.
Show resolved Hide resolved

inline bool IsValid() const { return 0 != addr_.sin_family; }
bool IsIpv4() const { return addr_.addr4_.sin_family == AF_INET; }
AlexStocks marked this conversation as resolved.
Show resolved Hide resolved

void Clear() { memset(&addr_, 0, sizeof addr_); }
void Clear() { memset(&addr_, 0, sizeof(addr_)); }

friend bool operator==(const SocketAddr &a, const SocketAddr &b) {
if (a.IsIpv4() != b.IsIpv4()) {
return false;
}

if (a.IsIpv4()) {
return a.addr_.addr4_.sin_addr.s_addr == b.addr_.addr4_.sin_addr.s_addr &&
a.addr_.addr4_.sin_port == b.addr_.addr4_.sin_port;
}

inline friend bool operator==(const SocketAddr &a, const SocketAddr &b) {
return a.addr_.sin_family == b.addr_.sin_family && a.addr_.sin_addr.s_addr == b.addr_.sin_addr.s_addr &&
a.addr_.sin_port == b.addr_.sin_port;
return memcmp(&a.addr_.addr6_.sin6_addr, &b.addr_.addr6_.sin6_addr, sizeof(in6_addr)) == 0 &&
a.addr_.addr6_.sin6_port == b.addr_.addr6_.sin6_port;
}

inline friend bool operator!=(const SocketAddr &a, const SocketAddr &b) { return !(a == b); }
friend bool operator!=(const SocketAddr &a, const SocketAddr &b) { return !(a == b); }

sockaddr_in addr_{};
union {
sockaddr_in addr4_;
sockaddr_in6 addr6_;
} addr_;
};

} // namespace net
Loading