Skip to content

Commit

Permalink
fix-http-resolve-for-ipv6
Browse files Browse the repository at this point in the history
  • Loading branch information
beef9999 committed Oct 30, 2023
1 parent 59fd620 commit 71bbe46
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 40 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.linux.arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Linux ARM

on:
push:
branches: [ "main" ]
branches: [ "main", "release/*" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "release/*" ]

jobs:
centos8-gcc921-epoll-release:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.linux.x86.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Linux x86

on:
push:
branches: [ "main" ]
branches: [ "main", "release/*" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "release/*" ]

jobs:
centos8-gcc921-epoll-release:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.macos.arm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: macOS ARM

on:
push:
branches: [ "main" ]
branches: [ "main", "release/*" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "release/*" ]

jobs:
macOS-clang-debug:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: macOS

on:
push:
branches: [ "main" ]
branches: [ "main", "release/*" ]
pull_request:
branches: [ "main" ]
branches: [ "main", "release/*" ]

jobs:
macOS-12-Monterey-debug:
Expand Down
65 changes: 46 additions & 19 deletions doc/docs/api/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ Network lib provides non-blocking socket implementations for clients and servers
ISocketClient* new_tcp_socket_client();
ISocketServer* new_tcp_socket_server();

ISocketClient* new_tcp_socket_client_ipv6();
ISocketServer* new_tcp_socket_server_ipv6();

ISocketClient* new_uds_client();
ISocketServer* new_uds_server(bool autoremove = false);

Expand All @@ -42,6 +45,11 @@ ISocketClient* new_fstack_dpdk_socket_client();
ISocketServer* new_fstack_dpdk_socket_server();
```
:::note
An IPv6 socket server listening on `::0` can handle both v4 and v6 socket client.
:::
#### Class Method
```cpp
Expand Down Expand Up @@ -95,36 +103,55 @@ namespace net {
}
```
#### IPv4 Address
#### Address and Endpoint
```cpp
namespace photon {
namespace net {
union IPAddr {
// Save IP address as a 32 bits integer, or 4 bytes.
uint32_t addr = 0;
struct { uint8_t a, b, c, d; };
// Create from the Internet host address, in network byte order, or from string
struct IPAddr {
in6_addr addr;
// For compatibility, the default constructor is still 0.0.0.0 (IPv4)
IPAddr();
// V6 constructor (Internet Address)
explicit IPAddr(in6_addr internet_addr);
// V6 constructor (Network byte order)
IPAddr(uint32_t nl1, uint32_t nl2, uint32_t nl3, uint32_t nl4);
// V4 constructor (Internet Address)
explicit IPAddr(in_addr internet_addr);
// V4 constructor (Network byte order)
explicit IPAddr(uint32_t nl);
explicit IPAddr(const char* s)
// String constructor
explicit IPAddr(const char* s);
// Check if it's actually an IPv4 address mapped in IPV6
bool is_ipv4();
// We regard the default IPv4 0.0.0.0 as undefined
bool undefined();
// Should ONLY be used for IPv4 address
uint32_t to_nl() const;
void from_nl(uint32_t nl);
bool is_loopback() const;
bool is_broadcast() const;
bool is_link_local() const;
bool operator==(const IPAddr& rhs) const;
bool operator!=(const IPAddr& rhs) const;
static IPAddr V6None();
static IPAddr V6Any();
static IPAddr V6Loopback();
static IPAddr V4Broadcast();
static IPAddr V4Any();
static IPAddr V4Loopback();
};
// EndPoint represents IP address and port
// A default endpoint is undefined (0.0.0.0:0)
struct EndPoint {
IPAddr addr;
uint16_t port;
// convert from the typical struct sockaddr_in
sockaddr_in to_sockaddr_in() const;
void from_sockaddr_in(const struct sockaddr_in& addr_in);
uint16_t port = 0;
EndPoint() = default;
EndPoint(IPAddr ip, uint16_t port);
bool is_ipv4() const;
bool operator==(const EndPoint& rhs) const;
bool operator!=(const EndPoint& rhs) const;
bool undefined() const;
};
// operators to help logging IP addresses with alog
LogBuffer& operator << (LogBuffer& log, const IPAddr addr);
LogBuffer& operator << (LogBuffer& log, const EndPoint ep);
}
}
```
Expand Down
10 changes: 8 additions & 2 deletions doc/docs/introduction/how-to-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ cmake --build build -j

```bash
cd PhotonLibOS
# Use `brew info openssl` to find openssl path
cmake -B build -D OPENSSL_ROOT_DIR=/path/to/openssl/
cmake -B build
cmake --build build -j
```

Expand Down Expand Up @@ -178,3 +177,10 @@ ctest
| PHOTON_ENABLE_FSTACK_DPDK | OFF | Enable F-Stack and DPDK. Requires both. |
| PHOTON_ENABLE_EXTFS | OFF | Enable extfs. Requires `libe2fs` |

#### Example

If there is any shared lib you don't want Photon to link to on local host, build its static from source.

```bash
cmake -B build -D PHOTON_BUILD_DEPENDENCIES=ON -D PHOTON_GFLAGS_SOURCE=https://github.com/gflags/gflags/archive/refs/tags/v2.2.2.tar.gz
```
5 changes: 3 additions & 2 deletions net/http/test/client_function_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ TEST(http_client, get) {
auto op2 = client->new_operation(Verb::GET, target);
DEFER(delete op2);
op2->req.headers.content_length(0);
client->call(op2);
int ret = client->call(op2);
GTEST_ASSERT_EQ(0, ret);

char resp_body_buf[1024];
EXPECT_EQ(sizeof(socket_buf), op2->resp.resource_size());
auto ret = op2->resp.read(resp_body_buf, sizeof(socket_buf));
ret = op2->resp.read(resp_body_buf, sizeof(socket_buf));
EXPECT_EQ(sizeof(socket_buf), ret);
resp_body_buf[sizeof(socket_buf) - 1] = '\0';
LOG_DEBUG(resp_body_buf);
Expand Down
26 changes: 19 additions & 7 deletions net/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,23 +256,34 @@ bool Base64Decode(std::string_view in, std::string &out) {

class DefaultResolver : public Resolver {
public:
DefaultResolver(uint64_t cache_ttl, uint64_t resolve_timeout)
: dnscache_(cache_ttl), resolve_timeout_(resolve_timeout) {}
DefaultResolver(uint64_t cache_ttl, uint64_t resolve_timeout, bool ipv6)
: dnscache_(cache_ttl), resolve_timeout_(resolve_timeout), ipv6_(ipv6) {}
~DefaultResolver() { dnscache_.clear(); }

IPAddr resolve(const char *host) override {
auto ctr = [&]() -> IPAddr * {
auto *ip = new IPAddr();
std::vector<IPAddr> addrs;
photon::semaphore sem;
std::thread([&]() {
*ip = gethostbyname(host);
int ret = gethostbyname(host, addrs);
if (ret < 0) {
addrs.clear();
}
sem.signal(1);
}).detach();
auto ret = sem.wait(1, resolve_timeout_);
if (ret < 0 && errno == ETIMEDOUT) {
LOG_WARN("Domain resolution for ` timeout!", host);
return new IPAddr; // undefined addr
} else if (addrs.empty()) {
LOG_WARN("Domain resolution for ` failed", host);
return new IPAddr; // undefined addr
}
return ip;
for (auto& each : addrs) {
if ((each.is_ipv4() ^ !ipv6_) == 0)
return new IPAddr(each);
}
return new IPAddr; // undefined addr
};
return *(dnscache_.borrow(host, ctr));
}
Expand All @@ -287,10 +298,11 @@ class DefaultResolver : public Resolver {
private:
ObjectCache<std::string, IPAddr *> dnscache_;
uint64_t resolve_timeout_;
bool ipv6_;
};

Resolver* new_default_resolver(uint64_t cache_ttl, uint64_t resolve_timeout) {
return new DefaultResolver(cache_ttl, resolve_timeout);
Resolver* new_default_resolver(uint64_t cache_ttl, uint64_t resolve_timeout, bool ipv6) {
return new DefaultResolver(cache_ttl, resolve_timeout, ipv6);
}

} // namespace net
Expand Down
5 changes: 3 additions & 2 deletions net/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ bool zerocopy_available();
*/
class Resolver : public Object {
public:
// When failed, IPAddr(0) should be returned.
// When failed, return an Undefined IPAddr
// Normally dns servers return multiple ips in random order, choosing the first one should suffice.
virtual IPAddr resolve(const char* host) = 0;
virtual void resolve(const char* host, Delegate<void, IPAddr> func) = 0;
Expand All @@ -165,9 +165,10 @@ class Resolver : public Object {
*
* @param cache_ttl cache's lifetime in microseconds.
* @param resolve_timeout timeout in microseconds for domain resolution.
* @param ipv6 specify v4 or v6 domain name
* @return Resolver*
*/
Resolver* new_default_resolver(uint64_t cache_ttl = 3600UL * 1000000, uint64_t resolve_timeout = -1);
Resolver* new_default_resolver(uint64_t cache_ttl = 3600UL * 1000000, uint64_t resolve_timeout = -1, bool ipv6 = false);

} // namespace net
}

0 comments on commit 71bbe46

Please sign in to comment.