@@ -693,7 +693,7 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){
693
693
* Main Public Methods
694
694
* */
695
695
696
- bool AsyncClient::connect (IPAddress ip , uint16_t port){
696
+ bool AsyncClient::_connect ( ip_addr_t addr , uint16_t port){
697
697
if (_pcb){
698
698
log_w (" already connected, state %d" , _pcb->state );
699
699
return false ;
@@ -703,11 +703,7 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
703
703
return false ;
704
704
}
705
705
706
- ip_addr_t addr;
707
- addr.type = IPADDR_TYPE_V4;
708
- addr.u_addr .ip4 .addr = ip;
709
-
710
- tcp_pcb* pcb = tcp_new_ip_type (IPADDR_TYPE_V4);
706
+ tcp_pcb* pcb = tcp_new_ip_type (addr.type );
711
707
if (!pcb){
712
708
log_e (" pcb == NULL" );
713
709
return false ;
@@ -723,6 +719,22 @@ bool AsyncClient::connect(IPAddress ip, uint16_t port){
723
719
return true ;
724
720
}
725
721
722
+ bool AsyncClient::connect (IPAddress ip, uint16_t port){
723
+ ip_addr_t addr;
724
+ addr.type = IPADDR_TYPE_V4;
725
+ addr.u_addr .ip4 .addr = ip;
726
+
727
+ return _connect (addr, port);
728
+ }
729
+
730
+ bool AsyncClient::connect (IPv6Address ip, uint16_t port){
731
+ ip_addr_t addr;
732
+ addr.type = IPADDR_TYPE_V6;
733
+ memcpy (addr.u_addr .ip6 .addr , static_cast <const uint32_t *>(ip), sizeof (uint32_t ) * 4 );
734
+
735
+ return _connect (addr, port);
736
+ }
737
+
726
738
bool AsyncClient::connect (const char * host, uint16_t port){
727
739
ip_addr_t addr;
728
740
@@ -733,6 +745,9 @@ bool AsyncClient::connect(const char* host, uint16_t port){
733
745
734
746
err_t err = dns_gethostbyname (host, &addr, (dns_found_callback)&_tcp_dns_found, this );
735
747
if (err == ERR_OK) {
748
+ if (addr.type == IPADDR_TYPE_V6) {
749
+ return connect (IPv6Address (addr.u_addr .ip6 .addr ), port);
750
+ }
736
751
return connect (IPAddress (addr.u_addr .ip4 .addr ), port);
737
752
} else if (err == ERR_INPROGRESS) {
738
753
_connect_port = port;
@@ -1000,7 +1015,9 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){
1000
1015
void AsyncClient::_dns_found (struct ip_addr *ipaddr){
1001
1016
if (ipaddr && ipaddr->u_addr .ip4 .addr ){
1002
1017
connect (IPAddress (ipaddr->u_addr .ip4 .addr ), _connect_port);
1003
- } else {
1018
+ } else if (ipaddr && ipaddr->u_addr .ip6 .addr ){
1019
+ connect (IPv6Address (ipaddr->u_addr .ip6 .addr ), _connect_port);
1020
+ else {
1004
1021
if (_error_cb) {
1005
1022
_error_cb (_error_cb_arg, this , -55 );
1006
1023
}
@@ -1091,6 +1108,15 @@ uint32_t AsyncClient::getRemoteAddress() {
1091
1108
return _pcb->remote_ip .u_addr .ip4 .addr ;
1092
1109
}
1093
1110
1111
+ ip6_addr_t AsyncClient::getRemoteAddress6 () {
1112
+ if (!_pcb) {
1113
+ ip6_addr_t nulladdr;
1114
+ ip6_addr_set_zero (&nulladdr);
1115
+ return nulladdr;
1116
+ }
1117
+ return _pcb->remote_ip .u_addr .ip6 ;
1118
+ }
1119
+
1094
1120
uint16_t AsyncClient::getRemotePort () {
1095
1121
if (!_pcb) {
1096
1122
return 0 ;
@@ -1105,6 +1131,15 @@ uint32_t AsyncClient::getLocalAddress() {
1105
1131
return _pcb->local_ip .u_addr .ip4 .addr ;
1106
1132
}
1107
1133
1134
+ ip6_addr_t AsyncClient::getLocalAddress6 () {
1135
+ if (!_pcb) {
1136
+ ip6_addr_t nulladdr;
1137
+ ip6_addr_set_zero (&nulladdr);
1138
+ return nulladdr;
1139
+ }
1140
+ return _pcb->local_ip .u_addr .ip6 ;
1141
+ }
1142
+
1108
1143
uint16_t AsyncClient::getLocalPort () {
1109
1144
if (!_pcb) {
1110
1145
return 0 ;
@@ -1116,14 +1151,24 @@ IPAddress AsyncClient::remoteIP() {
1116
1151
return IPAddress (getRemoteAddress ());
1117
1152
}
1118
1153
1154
+ IPv6Address AsyncClient::remoteIP6 () {
1155
+ return IPv6Address (getRemoteAddress6 ().addr );
1156
+ }
1157
+
1158
+
1119
1159
uint16_t AsyncClient::remotePort () {
1120
1160
return getRemotePort ();
1121
1161
}
1122
1162
1163
+
1123
1164
IPAddress AsyncClient::localIP () {
1124
1165
return IPAddress (getLocalAddress ());
1125
1166
}
1126
1167
1168
+ IPv6Address AsyncClient::localIP6 () {
1169
+ return IPv6Address (getLocalAddress6 ().addr );
1170
+ }
1171
+
1127
1172
uint16_t AsyncClient::localPort () {
1128
1173
return getLocalPort ();
1129
1174
}
@@ -1256,16 +1301,30 @@ int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){
1256
1301
1257
1302
AsyncServer::AsyncServer (IPAddress addr, uint16_t port)
1258
1303
: _port (port)
1304
+ , _bind4 (true )
1259
1305
, _addr (addr)
1260
1306
, _noDelay (false )
1261
1307
, _pcb (0 )
1262
1308
, _connect_cb (0 )
1263
1309
, _connect_cb_arg (0 )
1264
1310
{}
1265
1311
1312
+ AsyncServer::AsyncServer (IPv6Address addr, uint16_t port)
1313
+ : _port (port)
1314
+ , _bind6 (true )
1315
+ , _addr6 (addr)
1316
+ , _noDelay (false )
1317
+ , _pcb (0 )
1318
+ , _connect_cb (0 )
1319
+ , _connect_cb_arg (0 )
1320
+ {}
1321
+
1266
1322
AsyncServer::AsyncServer (uint16_t port)
1267
1323
: _port (port)
1324
+ , _bind4 (true )
1325
+ , _bind6 (true )
1268
1326
, _addr ((uint32_t ) IPADDR_ANY)
1327
+ , _addr6 ()
1269
1328
, _noDelay (false )
1270
1329
, _pcb (0 )
1271
1330
, _connect_cb (0 )
@@ -1290,16 +1349,26 @@ void AsyncServer::begin(){
1290
1349
log_e (" failed to start task" );
1291
1350
return ;
1292
1351
}
1293
- int8_t err;
1294
- _pcb = tcp_new_ip_type (IPADDR_TYPE_V4);
1352
+ int8_t err, bind_type;
1353
+
1354
+ if (_bind4 && _bind6) {
1355
+ bind_type = IPADDR_TYPE_ANY;
1356
+ } else if (_bind6) {
1357
+ bind_type = IPADDR_TYPE_V6;
1358
+ } else {
1359
+ bind_type = IPADDR_TYPE_V4;
1360
+ }
1361
+
1362
+ _pcb = tcp_new_ip_type (bind_type);
1295
1363
if (!_pcb){
1296
1364
log_e (" _pcb == NULL" );
1297
1365
return ;
1298
1366
}
1299
1367
1300
1368
ip_addr_t local_addr;
1301
- local_addr.type = IPADDR_TYPE_V4 ;
1369
+ local_addr.type = bind_type ;
1302
1370
local_addr.u_addr .ip4 .addr = (uint32_t ) _addr;
1371
+ memcpy (local_addr.u_addr .ip6 .addr , static_cast <const uint32_t *>(_addr6), sizeof (uint32_t ) * 4 );
1303
1372
err = _tcp_bind (_pcb, &local_addr, _port);
1304
1373
1305
1374
if (err != ERR_OK) {
0 commit comments