mirror of
https://github.com/me-no-dev/AsyncTCP.git
synced 2025-08-02 12:14:41 +02:00
IPv6 support added (#5)
Co-authored-by: Paweł pidpawel Kozubal <pawel.kozubal@husarnet.com>
This commit is contained in:
103
src/AsyncTCP.cpp
103
src/AsyncTCP.cpp
@@ -695,7 +695,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
|
|||||||
* Main Public Methods
|
* Main Public Methods
|
||||||
* */
|
* */
|
||||||
|
|
||||||
bool AsyncClient::connect(IPAddress ip, uint16_t port){
|
bool AsyncClient::_connect(ip_addr_t addr, uint16_t port){
|
||||||
if (_pcb){
|
if (_pcb){
|
||||||
log_w("already connected, state %d", _pcb->state);
|
log_w("already connected, state %d", _pcb->state);
|
||||||
return false;
|
return false;
|
||||||
@@ -705,15 +705,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_addr_t addr;
|
tcp_pcb* pcb = tcp_new_ip_type(addr.type);
|
||||||
#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);
|
|
||||||
if (!pcb){
|
if (!pcb){
|
||||||
log_e("pcb == NULL");
|
log_e("pcb == NULL");
|
||||||
return false;
|
return false;
|
||||||
@@ -724,22 +716,39 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
|
|||||||
tcp_recv(pcb, &_tcp_recv);
|
tcp_recv(pcb, &_tcp_recv);
|
||||||
tcp_sent(pcb, &_tcp_sent);
|
tcp_sent(pcb, &_tcp_sent);
|
||||||
tcp_poll(pcb, &_tcp_poll, 1);
|
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);
|
_tcp_connect(pcb, _closed_slot, &addr, port,(tcp_connected_fn)&_tcp_connected);
|
||||||
return true;
|
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){
|
bool AsyncClient::connect(const char* host, uint16_t port){
|
||||||
ip_addr_t addr;
|
ip_addr_t addr;
|
||||||
|
|
||||||
if(!_start_async_task()){
|
if(!_start_async_task()){
|
||||||
log_e("failed to start task");
|
log_e("failed to start task");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
|
err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this);
|
||||||
if(err == ERR_OK) {
|
if(err == ERR_OK) {
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
if(addr.type == IPADDR_TYPE_V6) {
|
||||||
|
return connect(IPv6Address(addr.u_addr.ip6.addr), port);
|
||||||
|
}
|
||||||
return connect(IPAddress(addr.u_addr.ip4.addr), port);
|
return connect(IPAddress(addr.u_addr.ip4.addr), port);
|
||||||
#else
|
#else
|
||||||
return connect(IPAddress(addr.addr), port);
|
return connect(IPAddress(addr.addr), port);
|
||||||
@@ -1011,10 +1020,8 @@ void AsyncClient::_dns_found(struct ip_addr *ipaddr){
|
|||||||
#if LWIP_IPV4 && LWIP_IPV6
|
#if LWIP_IPV4 && LWIP_IPV6
|
||||||
if(ipaddr && ipaddr->u_addr.ip4.addr){
|
if(ipaddr && ipaddr->u_addr.ip4.addr){
|
||||||
connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port);
|
connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port);
|
||||||
#else
|
} else if(ipaddr && ipaddr->u_addr.ip6.addr){
|
||||||
if (ipaddr && ipaddr->addr){
|
connect(IPv6Address(ipaddr->u_addr.ip6.addr), _connect_port);
|
||||||
connect(IPAddress(ipaddr->addr), _connect_port);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
if(_error_cb) {
|
if(_error_cb) {
|
||||||
_error_cb(_error_cb_arg, this, -55);
|
_error_cb(_error_cb_arg, this, -55);
|
||||||
@@ -1110,6 +1117,15 @@ uint32_t AsyncClient::getRemoteAddress() {
|
|||||||
#endif
|
#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() {
|
uint16_t AsyncClient::getRemotePort() {
|
||||||
if(!_pcb) {
|
if(!_pcb) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1128,6 +1144,15 @@ uint32_t AsyncClient::getLocalAddress() {
|
|||||||
#endif
|
#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() {
|
uint16_t AsyncClient::getLocalPort() {
|
||||||
if(!_pcb) {
|
if(!_pcb) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1139,6 +1164,10 @@ IPAddress AsyncClient::remoteIP() {
|
|||||||
return IPAddress(getRemoteAddress());
|
return IPAddress(getRemoteAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPv6Address AsyncClient::remoteIP6() {
|
||||||
|
return IPv6Address(getRemoteAddress6().addr);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t AsyncClient::remotePort() {
|
uint16_t AsyncClient::remotePort() {
|
||||||
return getRemotePort();
|
return getRemotePort();
|
||||||
}
|
}
|
||||||
@@ -1147,6 +1176,10 @@ IPAddress AsyncClient::localIP() {
|
|||||||
return IPAddress(getLocalAddress());
|
return IPAddress(getLocalAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPv6Address AsyncClient::localIP6() {
|
||||||
|
return IPv6Address(getLocalAddress6().addr);
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t AsyncClient::localPort() {
|
uint16_t AsyncClient::localPort() {
|
||||||
return getLocalPort();
|
return getLocalPort();
|
||||||
}
|
}
|
||||||
@@ -1279,6 +1312,7 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){
|
|||||||
|
|
||||||
AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
|
AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
|
||||||
: _port(port)
|
: _port(port)
|
||||||
|
, _bind4(true)
|
||||||
, _addr(addr)
|
, _addr(addr)
|
||||||
, _noDelay(false)
|
, _noDelay(false)
|
||||||
, _pcb(0)
|
, _pcb(0)
|
||||||
@@ -1286,9 +1320,22 @@ AsyncServer::AsyncServer(IPAddress addr, uint16_t port)
|
|||||||
, _connect_cb_arg(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)
|
AsyncServer::AsyncServer(uint16_t port)
|
||||||
: _port(port)
|
: _port(port)
|
||||||
|
, _bind4(true)
|
||||||
|
, _bind6(true)
|
||||||
, _addr((uint32_t) IPADDR_ANY)
|
, _addr((uint32_t) IPADDR_ANY)
|
||||||
|
, _addr6()
|
||||||
, _noDelay(false)
|
, _noDelay(false)
|
||||||
, _pcb(0)
|
, _pcb(0)
|
||||||
, _connect_cb(0)
|
, _connect_cb(0)
|
||||||
@@ -1313,20 +1360,26 @@ void AsyncServer::begin(){
|
|||||||
log_e("failed to start task");
|
log_e("failed to start task");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int8_t err;
|
int8_t err, bind_type;
|
||||||
_pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
|
|
||||||
|
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){
|
if (!_pcb){
|
||||||
log_e("_pcb == NULL");
|
log_e("_pcb == NULL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_addr_t local_addr;
|
ip_addr_t local_addr;
|
||||||
#if LWIP_IPV4 && LWIP_IPV6
|
local_addr.type = bind_type;
|
||||||
local_addr.type = IPADDR_TYPE_V4;
|
|
||||||
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
|
local_addr.u_addr.ip4.addr = (uint32_t) _addr;
|
||||||
#else
|
memcpy(local_addr.u_addr.ip6.addr, static_cast<const uint32_t*>(_addr6), sizeof(uint32_t) * 4);
|
||||||
local_addr.addr = (uint32_t) _addr;
|
|
||||||
#endif
|
|
||||||
err = _tcp_bind(_pcb, &local_addr, _port);
|
err = _tcp_bind(_pcb, &local_addr, _port);
|
||||||
|
|
||||||
if (err != ERR_OK) {
|
if (err != ERR_OK) {
|
||||||
|
@@ -23,6 +23,8 @@
|
|||||||
#define ASYNCTCP_H_
|
#define ASYNCTCP_H_
|
||||||
|
|
||||||
#include "IPAddress.h"
|
#include "IPAddress.h"
|
||||||
|
#include "IPv6Address.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#ifndef LIBRETINY
|
#ifndef LIBRETINY
|
||||||
@@ -30,6 +32,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
|
#include "lwip/ip_addr.h"
|
||||||
|
#include "lwip/ip6_addr.h"
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -80,7 +84,8 @@ class AsyncClient {
|
|||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
bool connect(IPAddress ip, uint16_t port);
|
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 close(bool now = false);
|
||||||
void stop();
|
void stop();
|
||||||
int8_t abort();
|
int8_t abort();
|
||||||
@@ -114,15 +119,19 @@ class AsyncClient {
|
|||||||
bool getNoDelay();
|
bool getNoDelay();
|
||||||
|
|
||||||
uint32_t getRemoteAddress();
|
uint32_t getRemoteAddress();
|
||||||
|
ip6_addr_t getRemoteAddress6();
|
||||||
uint16_t getRemotePort();
|
uint16_t getRemotePort();
|
||||||
uint32_t getLocalAddress();
|
uint32_t getLocalAddress();
|
||||||
|
ip6_addr_t getLocalAddress6();
|
||||||
uint16_t getLocalPort();
|
uint16_t getLocalPort();
|
||||||
|
|
||||||
//compatibility
|
//compatibility
|
||||||
IPAddress remoteIP();
|
IPAddress remoteIP();
|
||||||
uint16_t remotePort();
|
IPv6Address remoteIP6();
|
||||||
|
uint16_t remotePort();
|
||||||
IPAddress localIP();
|
IPAddress localIP();
|
||||||
uint16_t localPort();
|
IPv6Address localIP6();
|
||||||
|
uint16_t localPort();
|
||||||
|
|
||||||
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
|
void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect
|
||||||
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
|
void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected
|
||||||
@@ -154,6 +163,8 @@ class AsyncClient {
|
|||||||
tcp_pcb * pcb(){ return _pcb; }
|
tcp_pcb * pcb(){ return _pcb; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
bool _connect(ip_addr_t addr, uint16_t port);
|
||||||
|
|
||||||
tcp_pcb* _pcb;
|
tcp_pcb* _pcb;
|
||||||
int8_t _closed_slot;
|
int8_t _closed_slot;
|
||||||
|
|
||||||
@@ -202,6 +213,7 @@ class AsyncClient {
|
|||||||
class AsyncServer {
|
class AsyncServer {
|
||||||
public:
|
public:
|
||||||
AsyncServer(IPAddress addr, uint16_t port);
|
AsyncServer(IPAddress addr, uint16_t port);
|
||||||
|
AsyncServer(IPv6Address addr, uint16_t port);
|
||||||
AsyncServer(uint16_t port);
|
AsyncServer(uint16_t port);
|
||||||
~AsyncServer();
|
~AsyncServer();
|
||||||
void onClient(AcConnectHandler cb, void* arg);
|
void onClient(AcConnectHandler cb, void* arg);
|
||||||
@@ -217,7 +229,10 @@ class AsyncServer {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint16_t _port;
|
uint16_t _port;
|
||||||
|
bool _bind4 = false;
|
||||||
|
bool _bind6 = false;
|
||||||
IPAddress _addr;
|
IPAddress _addr;
|
||||||
|
IPv6Address _addr6;
|
||||||
bool _noDelay;
|
bool _noDelay;
|
||||||
tcp_pcb* _pcb;
|
tcp_pcb* _pcb;
|
||||||
AcConnectHandler _connect_cb;
|
AcConnectHandler _connect_cb;
|
||||||
|
Reference in New Issue
Block a user