Skip to content

IPv6 support added #5

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

Merged
merged 1 commit into from
Dec 21, 2023
Merged
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
103 changes: 78 additions & 25 deletions src/AsyncTCP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
* Main Public Methods
* */

bool AsyncClient::connect(IPAddress ip, uint16_t port){
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port){
if (_pcb){
log_w("already connected, state %d", _pcb->state);
return false;
Expand All @@ -705,15 +705,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
return false;
}

ip_addr_t addr;
#if LWIP_IPV4 && LWIP_IPV6
addr.type = IPADDR_TYPE_V4;
addr.u_addr.ip4.addr = ip;
#else
addr.addr = ip;
#endif

tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
tcp_pcb* pcb = tcp_new_ip_type(addr.type);
if (!pcb){
log_e("pcb == NULL");
return false;
Expand All @@ -724,22 +716,39 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
tcp_recv(pcb, &_tcp_recv);
tcp_sent(pcb, &_tcp_sent);
tcp_poll(pcb, &_tcp_poll, 1);
//_tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
_tcp_connect(pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
return true;
}

bool AsyncClient::connect(IPAddress ip, uint16_t port){
ip_addr_t addr;
addr.type = IPADDR_TYPE_V4;
addr.u_addr.ip4.addr = ip;

return _connect(addr, port);
}

bool AsyncClient::connect(IPv6Address ip, uint16_t port){
ip_addr_t addr;
addr.type = IPADDR_TYPE_V6;
memcpy(addr.u_addr.ip6.addr, static_cast<const uint32_t*>(ip), sizeof(uint32_t) * 4);

return _connect(addr, port);
}

bool AsyncClient::connect(const char* host, uint16_t port){
ip_addr_t addr;

if(!_start_async_task()){
log_e("failed to start task");
return false;
}

err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
if(err == ERR_OK) {
#if LWIP_IPV4 && LWIP_IPV6

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the removal of this ifdef might be causing the build issues.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I saw too. I switched back to the previous version in my project.

if(addr.type == IPADDR_TYPE_V6) {
return connect(IPv6Address(addr.u_addr.ip6.addr), port);
}
return connect(IPAddress(addr.u_addr.ip4.addr), port);
#else
return connect(IPAddress(addr.addr), port);
Expand Down Expand Up @@ -1011,10 +1020,8 @@ void AsyncClient::_dns_found(struct ip_addr *ipaddr){
#if LWIP_IPV4 && LWIP_IPV6
if(ipaddr && ipaddr->u_addr.ip4.addr){
connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port);
#else
if (ipaddr && ipaddr->addr){
connect(IPAddress(ipaddr->addr), _connect_port);
#endif
} else if(ipaddr && ipaddr->u_addr.ip6.addr){
connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
} else {
if(_error_cb) {
_error_cb(_error_cb_arg, this, -55);
Expand Down Expand Up @@ -1110,6 +1117,15 @@ uint32_t AsyncClient::getRemoteAddress() {
#endif
}

ip6_addr_t AsyncClient::getRemoteAddress6() {
if(!_pcb) {
ip6_addr_t nulladdr;
ip6_addr_set_zero(&nulladdr);
return nulladdr;
}
return _pcb->remote_ip.u_addr.ip6;
}

uint16_t AsyncClient::getRemotePort() {
if(!_pcb) {
return 0;
Expand All @@ -1128,6 +1144,15 @@ uint32_t AsyncClient::getLocalAddress() {
#endif
}

ip6_addr_t AsyncClient::getLocalAddress6() {
if(!_pcb) {
ip6_addr_t nulladdr;
ip6_addr_set_zero(&nulladdr);
return nulladdr;
}
return _pcb->local_ip.u_addr.ip6;
}

uint16_t AsyncClient::getLocalPort() {
if(!_pcb) {
return 0;
Expand All @@ -1139,6 +1164,10 @@ IPAddress AsyncClient::remoteIP() {
return IPAddress(getRemoteAddress());
}

IPv6Address AsyncClient::remoteIP6() {
return IPv6Address(getRemoteAddress6().addr);
}

uint16_t AsyncClient::remotePort() {
return getRemotePort();
}
Expand All @@ -1147,6 +1176,10 @@ IPAddress AsyncClient::localIP() {
return IPAddress(getLocalAddress());
}

IPv6Address AsyncClient::localIP6() {
return IPv6Address(getLocalAddress6().addr);
}

uint16_t AsyncClient::localPort() {
return getLocalPort();
}
Expand Down Expand Up @@ -1279,16 +1312,30 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){

AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
: _port(port)
, _bind4(true)
, _addr(addr)
, _noDelay(false)
, _pcb(0)
, _connect_cb(0)
, _connect_cb_arg(0)
{}

AsyncServer::AsyncServer(IPv6Address addr, uint16_t port)
: _port(port)
, _bind6(true)
, _addr6(addr)
, _noDelay(false)
, _pcb(0)
, _connect_cb(0)
, _connect_cb_arg(0)
{}

AsyncServer::AsyncServer(uint16_t port)
: _port(port)
, _bind4(true)
, _bind6(true)
, _addr((uint32_t) IPADDR_ANY)
, _addr6()
, _noDelay(false)
, _pcb(0)
, _connect_cb(0)
Expand All @@ -1313,20 +1360,26 @@ void AsyncServer::begin(){
log_e("failed to start task");
return;
}
int8_t err;
_pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
int8_t err, bind_type;

if(_bind4 && _bind6) {
bind_type = IPADDR_TYPE_ANY;
} else if (_bind6) {
bind_type = IPADDR_TYPE_V6;
} else {
bind_type = IPADDR_TYPE_V4;
}

_pcb = tcp_new_ip_type(bind_type);
if (!_pcb){
log_e("_pcb == NULL");
return;
}

ip_addr_t local_addr;
#if LWIP_IPV4 && LWIP_IPV6
local_addr.type = IPADDR_TYPE_V4;
local_addr.type = bind_type;
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
#else
local_addr.addr = (uint32_t) _addr;
#endif
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t*>(_addr6), sizeof(uint32_t) * 4);
err = _tcp_bind(_pcb, &local_addr, _port);

if (err != ERR_OK) {
Expand Down
21 changes: 18 additions & 3 deletions src/AsyncTCP.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@
#define ASYNCTCP_H_

#include "IPAddress.h"
#include "IPv6Address.h"
#include "sdkconfig.h"
#include <functional>

#ifndef LIBRETINY
#include "sdkconfig.h"
extern "C" {
#include "freertos/semphr.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/ip6_addr.h"
}
#else
extern "C" {
Expand Down Expand Up @@ -80,7 +84,8 @@ class AsyncClient {
return !(*this == other);
}
bool connect(IPAddress ip, uint16_t port);
bool connect(const char* host, uint16_t port);
bool connect(IPv6Address ip, uint16_t port);
bool connect(const char *host, uint16_t port);
void close(bool now = false);
void stop();
int8_t abort();
Expand Down Expand Up @@ -114,15 +119,19 @@ class AsyncClient {
bool getNoDelay();

uint32_t getRemoteAddress();
ip6_addr_t getRemoteAddress6();
uint16_t getRemotePort();
uint32_t getLocalAddress();
ip6_addr_t getLocalAddress6();
uint16_t getLocalPort();

//compatibility
IPAddress remoteIP();
uint16_t remotePort();
IPv6Address remoteIP6();
uint16_t remotePort();
IPAddress localIP();
uint16_t localPort();
IPv6Address localIP6();
uint16_t localPort();

void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
Expand Down Expand Up @@ -154,6 +163,8 @@ class AsyncClient {
tcp_pcb * pcb(){ return _pcb; }

protected:
bool _connect(ip_addr_t addr, uint16_t port);

tcp_pcb* _pcb;
int8_t _closed_slot;

Expand Down Expand Up @@ -202,6 +213,7 @@ class AsyncClient {
class AsyncServer {
public:
AsyncServer(IPAddress addr, uint16_t port);
AsyncServer(IPv6Address addr, uint16_t port);
AsyncServer(uint16_t port);
~AsyncServer();
void onClient(AcConnectHandler cb, void* arg);
Expand All @@ -217,7 +229,10 @@ class AsyncServer {

protected:
uint16_t _port;
bool _bind4 = false;
bool _bind6 = false;
IPAddress _addr;
IPv6Address _addr6;
bool _noDelay;
tcp_pcb* _pcb;
AcConnectHandler _connect_cb;
Expand Down