diff --git a/cores/esp32/Client.h b/cores/esp32/Client.h
index 962cacc51da..c575cde0c66 100644
--- a/cores/esp32/Client.h
+++ b/cores/esp32/Client.h
@@ -22,6 +22,7 @@
 #include "Print.h"
 #include "Stream.h"
 #include "IPAddress.h"
+#include "IPv6Address.h"
 
 class Client: public Stream
 {
diff --git a/libraries/WiFi/examples/WiFiTelnetToSerialIPv6/WiFiTelnetToSerialIPv6.ino b/libraries/WiFi/examples/WiFiTelnetToSerialIPv6/WiFiTelnetToSerialIPv6.ino
new file mode 100644
index 00000000000..99b1c0c82e9
--- /dev/null
+++ b/libraries/WiFi/examples/WiFiTelnetToSerialIPv6/WiFiTelnetToSerialIPv6.ino
@@ -0,0 +1,132 @@
+/*
+  WiFiTelnetToSerial - Example Transparent UART to Telnet Server for ESP32
+
+  Copyright (c) 2017 Hristo Gochkov. All rights reserved.
+  This file is part of the ESP32 WiFi library for Arduino environment.
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+#include <WiFi.h>
+#include <WiFiMulti.h>
+
+WiFiMulti wifiMulti;
+
+//Even this example state IPv6, it is dual stack and compatible with IPv4 too
+
+//how many clients should be able to telnet to this ESP32
+#define MAX_SRV_CLIENTS 1
+const char* ssid = "**********";
+const char* password = "**********";
+
+WiFiServer server(23);
+WiFiClient serverClients[MAX_SRV_CLIENTS];
+
+void setup() {
+  Serial.begin(115200);
+  Serial.println("\nConnecting");
+
+  wifiMulti.IPv6(true);
+  wifiMulti.addAP(ssid, password);
+  wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
+  wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
+
+  Serial.println("Connecting Wifi ");
+  for (int loops = 10; loops > 0; loops--) {
+    if (wifiMulti.run() == WL_CONNECTED) {
+      Serial.println("");
+      Serial.print("WiFi connected ");
+      Serial.print("IP address: ");
+      Serial.println(WiFi.localIP());
+      break;
+    }
+    else {
+      Serial.println(loops);
+      delay(1000);
+    }
+  }
+  if (wifiMulti.run() != WL_CONNECTED) {
+    Serial.println("WiFi connect failed");
+    delay(1000);
+    ESP.restart();
+  }
+
+  //start UART and the server
+  Serial1.begin(9600);
+  server.begin();
+  server.setNoDelay(true);
+
+  Serial.print("Ready! Use 'telnet ");
+  Serial.print(WiFi.localIP());
+  Serial.println(" 23' to connect");
+}
+
+void loop() {
+  uint8_t i;
+  if (wifiMulti.run() == WL_CONNECTED) {
+    //check if there are any new clients
+    if (server.hasClient()){
+      for(i = 0; i < MAX_SRV_CLIENTS; i++){
+        //find free/disconnected spot
+        if (!serverClients[i] || !serverClients[i].connected()){
+          if(serverClients[i]) serverClients[i].stop();
+          serverClients[i] = server.available();
+          if (!serverClients[i]) Serial.println("available broken");
+          Serial.print("New client: ");
+          Serial.print(i); Serial.print(' ');
+          Serial.println(serverClients[i].remoteIP6());
+          break;
+        }
+      }
+      if (i >= MAX_SRV_CLIENTS) {
+        //no free/disconnected spot so reject
+        server.available().stop();
+      }
+    }
+    //check clients for data
+    for(i = 0; i < MAX_SRV_CLIENTS; i++){
+      if (serverClients[i] && serverClients[i].connected()){
+        if(serverClients[i].available()){
+          //get data from the telnet client and push it to the UART
+          while(serverClients[i].available()) Serial1.write(serverClients[i].read());
+        }
+      }
+      else {
+        if (serverClients[i]) {
+          serverClients[i].stop();
+        }
+      }
+    }
+    //check UART for data
+    if(Serial1.available()){
+      size_t len = Serial1.available();
+      uint8_t sbuf[len];
+      Serial1.readBytes(sbuf, len);
+      //push UART data to all connected telnet clients
+      for(i = 0; i < MAX_SRV_CLIENTS; i++){
+        if (serverClients[i] && serverClients[i].connected()){
+          serverClients[i].write(sbuf, len);
+          delay(1);
+        }
+      }
+    }
+  }
+  else {
+    Serial.println("WiFi not connected!");
+    for(i = 0; i < MAX_SRV_CLIENTS; i++) {
+      if (serverClients[i]) serverClients[i].stop();
+    }
+    delay(1000);
+  }
+}
diff --git a/libraries/WiFi/src/WiFiClient.cpp b/libraries/WiFi/src/WiFiClient.cpp
index 69a691995bd..d9587f6ff95 100644
--- a/libraries/WiFi/src/WiFiClient.cpp
+++ b/libraries/WiFi/src/WiFiClient.cpp
@@ -210,22 +210,43 @@ int WiFiClient::connect(IPAddress ip, uint16_t port)
 {
     return connect(ip,port,_timeout);
 }
+
 int WiFiClient::connect(IPAddress ip, uint16_t port, int32_t timeout)
 {
+    ip_addr_t dstip;
+    dstip = IPADDR_ANY_TYPE_INIT;
+    IP_ADDR4(&dstip, ip[0], ip[1], ip[2], ip[3]);
+    return connect(dstip, port, timeout);
+}
+
+int WiFiClient::connect(ip_addr_t ip, uint16_t port, int32_t timeout)
+{
+    struct sockaddr_storage serveraddr;
     _timeout = timeout;
-    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
+    int sockfd = -1;
+
+    if (IP_IS_V6(&ip)) {
+        sockfd = socket(AF_INET6, SOCK_STREAM, 0);
+        struct sockaddr_in6 *tmpaddr = (struct sockaddr_in6 *)&serveraddr;
+        memset((char *) tmpaddr, 0, sizeof(struct sockaddr_in6));
+        tmpaddr->sin6_family = AF_INET6;
+        inet6_addr_from_ip6addr(&tmpaddr->sin6_addr, ip_2_ip6(&ip));
+        tmpaddr->sin6_port = htons(port);
+    }
+    if (sockfd == -1 && IP_IS_V4(&ip)) {
+        sockfd = socket(AF_INET, SOCK_STREAM, 0);
+        struct sockaddr_in *tmpaddr = (struct sockaddr_in *)&serveraddr;
+        memset((char *) tmpaddr, 0, sizeof(struct sockaddr_in));
+        tmpaddr->sin_family = AF_INET;
+        tmpaddr->sin_addr.s_addr = ip4_addr_get_u32(&ip.u_addr.ip4);
+        tmpaddr->sin_port = htons(port);
+    }
     if (sockfd < 0) {
         log_e("socket: %d", errno);
         return 0;
     }
     fcntl( sockfd, F_SETFL, fcntl( sockfd, F_GETFL, 0 ) | O_NONBLOCK );
 
-    uint32_t ip_addr = ip;
-    struct sockaddr_in serveraddr;
-    memset((char *) &serveraddr, 0, sizeof(serveraddr));
-    serveraddr.sin_family = AF_INET;
-    memcpy((void *)&serveraddr.sin_addr.s_addr, (const void *)(&ip_addr), 4);
-    serveraddr.sin_port = htons(port);
     fd_set fdset;
     struct timeval tv;
     FD_ZERO(&fdset);
@@ -294,6 +315,13 @@ int WiFiClient::connect(const char *host, uint16_t port)
 
 int WiFiClient::connect(const char *host, uint16_t port, int32_t timeout)
 {
+    if (WiFiGenericClass::getStatusBits() & WIFI_WANT_IP6_BIT) {
+        ip_addr_t srv6;
+        if(!WiFiGenericClass::hostByName6(host, srv6)){
+            return 0;
+        }
+        return connect(srv6, port, timeout);
+    }
     IPAddress srv((uint32_t)0);
     if(!WiFiGenericClass::hostByName(host, srv)){
         return 0;
@@ -561,8 +589,52 @@ IPAddress WiFiClient::remoteIP(int fd) const
     struct sockaddr_storage addr;
     socklen_t len = sizeof addr;
     getpeername(fd, (struct sockaddr*)&addr, &len);
-    struct sockaddr_in *s = (struct sockaddr_in *)&addr;
-    return IPAddress((uint32_t)(s->sin_addr.s_addr));
+
+    // Old way, IPv4
+    if (((struct sockaddr*)&addr)->sa_family == AF_INET) {
+        struct sockaddr_in *s = (struct sockaddr_in *)&addr;
+        return IPAddress((uint32_t)(s->sin_addr.s_addr));
+    }
+    // IPv6, but it might be IPv4 mapped address
+    if (((struct sockaddr*)&addr)->sa_family == AF_INET6) {
+        struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&addr;
+        if (IN6_IS_ADDR_V4MAPPED(saddr6->sin6_addr.un.u32_addr)) {
+            struct sockaddr_in addr4;
+            memset(&addr4, 0, sizeof(addr4));
+            addr4.sin_family = AF_INET;
+            addr4.sin_port = saddr6->sin6_port;
+            memcpy(&addr4.sin_addr.s_addr, saddr6->sin6_addr.s6_addr+12, sizeof(addr4.sin_addr.s_addr));
+            return IPAddress((uint32_t)(addr4.sin_addr.s_addr));
+        }
+        log_e("WiFiClient::remoteIP IPv6 to IPv4 cannot convert");
+        return (IPAddress(0,0,0,0));
+    }
+    log_e("WiFiClient::remoteIP Not AF_INET or AF_INET6?");
+    return (IPAddress(0,0,0,0));
+}
+
+IPv6Address WiFiClient::remoteIP6(int fd) const
+{
+    struct sockaddr_storage addr;
+    socklen_t len = sizeof addr;
+    getpeername(fd, (struct sockaddr*)&addr, &len);
+
+    // IPv4 socket we can print as IPv6 mapped
+    if (((struct sockaddr*)&addr)->sa_family == AF_INET) {
+        uint8_t buffer[16] = { 0 };
+        buffer[10] = 0xFF;
+        buffer[11] = 0xFF;
+        struct sockaddr_in *s = (struct sockaddr_in *)&addr;
+        memcpy(&buffer[12], (uint8_t*)&s->sin_addr.s_addr, 4);
+        return IPv6Address(buffer);
+    }
+    // IPv6
+    if (((struct sockaddr*)&addr)->sa_family == AF_INET6) {
+        struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&addr;
+        return (IPv6Address(saddr6->sin6_addr.s6_addr));
+    }
+    log_e("WiFiClient::remoteIP Not AF_INET or AF_INET6?");
+    return (IPv6Address());
 }
 
 uint16_t WiFiClient::remotePort(int fd) const
@@ -579,6 +651,11 @@ IPAddress WiFiClient::remoteIP() const
     return remoteIP(fd());
 }
 
+IPv6Address WiFiClient::remoteIP6() const
+{
+    return remoteIP6(fd());
+}
+
 uint16_t WiFiClient::remotePort() const
 {
     return remotePort(fd());
diff --git a/libraries/WiFi/src/WiFiClient.h b/libraries/WiFi/src/WiFiClient.h
index 5aaa6ba115e..e66772f9c2d 100644
--- a/libraries/WiFi/src/WiFiClient.h
+++ b/libraries/WiFi/src/WiFiClient.h
@@ -24,6 +24,7 @@
 #include "Arduino.h"
 #include "Client.h"
 #include <memory>
+#include "lwip/ip_addr.h"
 
 class WiFiClientSocketHandle;
 class WiFiClientRxBuffer;
@@ -49,6 +50,7 @@ class WiFiClient : public ESPLwIPClient
     WiFiClient();
     WiFiClient(int fd);
     ~WiFiClient();
+    int connect(ip_addr_t ip, uint16_t port, int32_t timeout);
     int connect(IPAddress ip, uint16_t port);
     int connect(IPAddress ip, uint16_t port, int32_t timeout);
     int connect(const char *host, uint16_t port);
@@ -95,6 +97,8 @@ class WiFiClient : public ESPLwIPClient
 
     IPAddress remoteIP() const;
     IPAddress remoteIP(int fd) const;
+    IPv6Address remoteIP6() const;
+    IPv6Address remoteIP6(int fd) const;    
     uint16_t remotePort() const;
     uint16_t remotePort(int fd) const;
     IPAddress localIP() const;
@@ -106,4 +110,9 @@ class WiFiClient : public ESPLwIPClient
     using Print::write;
 };
 
+#define IN6_IS_ADDR_V4MAPPED(a) \
+        ((((__const uint32_t *) (a))[0] == 0)                                 \
+         && (((__const uint32_t *) (a))[1] == 0)                              \
+         && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
+
 #endif /* _WIFICLIENT_H_ */
diff --git a/libraries/WiFi/src/WiFiGeneric.cpp b/libraries/WiFi/src/WiFiGeneric.cpp
index 5d31341481a..7b9b1c31b09 100644
--- a/libraries/WiFi/src/WiFiGeneric.cpp
+++ b/libraries/WiFi/src/WiFiGeneric.cpp
@@ -866,8 +866,8 @@ esp_err_t WiFiGenericClass::_eventCallback(arduino_event_t *event)
     } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_CONNECTED) {
         WiFiSTAClass::_setStatus(WL_IDLE_STATUS);
         setStatusBits(STA_CONNECTED_BIT);
-
-        //esp_netif_create_ip6_linklocal(esp_netifs[ESP_IF_WIFI_STA]);
+        if (getStatusBits() & WIFI_WANT_IP6_BIT)
+            esp_netif_create_ip6_linklocal(esp_netifs[ESP_IF_WIFI_STA]);
     } else if(event->event_id == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
         uint8_t reason = event->event_info.wifi_sta_disconnected.reason;
         log_w("Reason: %u - %s", reason, reason2str(reason));
@@ -1335,6 +1335,25 @@ static void wifi_dns_found_callback(const char *name, const ip_addr_t *ipaddr, v
     xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT);
 }
 
+/**
+ * IPv6 compatible DNS callback
+ * @param name
+ * @param ipaddr
+ * @param callback_arg
+ */
+static void wifi_dns6_found_callback(const char *name, const ip_addr_t *ipaddr, void *callback_arg)
+{
+    struct dns_api_msg *msg = (struct dns_api_msg *)callback_arg;
+
+    if(ipaddr && !msg->result) {
+        msg->ip_addr = *ipaddr;
+        msg->result = 1;
+    } else {
+        msg->result = -1;
+    }
+    xEventGroupSetBits(_arduino_event_group, WIFI_DNS_DONE_BIT);
+}
+
 /**
  * Resolve the given hostname to an IP address.
  * @param aHostname     Name to be resolved
@@ -1362,6 +1381,36 @@ int WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult)
     return (uint32_t)aResult != 0;
 }
 
+/**
+ * Resolve the given hostname to an IP6 address.
+ * @param aHostname     Name to be resolved
+ * @param aResult       IPv6Address structure to store the returned IP address
+ * @return 1 if aHostname was successfully converted to an IP address,
+ *          else error code
+ */
+int WiFiGenericClass::hostByName6(const char* aHostname, ip_addr_t& aResult)
+{
+    ip_addr_t addr;
+    struct dns_api_msg arg;
+
+    memset(&arg, 0x0, sizeof(arg));
+    waitStatusBits(WIFI_DNS_IDLE_BIT, 16000);
+    clearStatusBits(WIFI_DNS_IDLE_BIT | WIFI_DNS_DONE_BIT);
+
+    err_t err = dns_gethostbyname_addrtype(aHostname, &addr, &wifi_dns6_found_callback,
+                &arg, LWIP_DNS_ADDRTYPE_IPV6_IPV4);
+    if(err == ERR_OK) {
+        aResult = addr;
+    } else if(err == ERR_INPROGRESS) {
+        waitStatusBits(WIFI_DNS_DONE_BIT, 15000);  //real internal timeout in lwip library is 14[s]
+        clearStatusBits(WIFI_DNS_DONE_BIT);
+        if (arg.result == 1)
+            aResult = arg.ip_addr;
+    }
+    setStatusBits(WIFI_DNS_IDLE_BIT);
+    return (uint32_t)err == ERR_OK || (err == ERR_INPROGRESS && arg.result == 1);
+}
+
 IPAddress WiFiGenericClass::calculateNetworkID(IPAddress ip, IPAddress subnet) {
 	IPAddress networkID;
 
diff --git a/libraries/WiFi/src/WiFiGeneric.h b/libraries/WiFi/src/WiFiGeneric.h
index 62642b43dc7..6957e68d73e 100644
--- a/libraries/WiFi/src/WiFiGeneric.h
+++ b/libraries/WiFi/src/WiFiGeneric.h
@@ -138,6 +138,7 @@ static const int WIFI_SCANNING_BIT = BIT11;
 static const int WIFI_SCAN_DONE_BIT= BIT12;
 static const int WIFI_DNS_IDLE_BIT = BIT13;
 static const int WIFI_DNS_DONE_BIT = BIT14;
+static const int WIFI_WANT_IP6_BIT = BIT15;
 
 typedef enum {
 	WIFI_RX_ANT0 = 0,
@@ -151,6 +152,11 @@ typedef enum {
 	WIFI_TX_ANT_AUTO
 } wifi_tx_ant_t;
 
+struct dns_api_msg {
+    ip_addr_t ip_addr;
+    int result;
+};
+
 class WiFiGenericClass
 {
   public:
@@ -209,6 +215,7 @@ class WiFiGenericClass
     
   public:
     static int hostByName(const char *aHostname, IPAddress &aResult);
+    static int hostByName6(const char *aHostname, ip_addr_t &aResult);
 
     static IPAddress calculateNetworkID(IPAddress ip, IPAddress subnet);
     static IPAddress calculateBroadcast(IPAddress ip, IPAddress subnet);
diff --git a/libraries/WiFi/src/WiFiMulti.cpp b/libraries/WiFi/src/WiFiMulti.cpp
index 3d69e481293..52c9b2bf41e 100644
--- a/libraries/WiFi/src/WiFiMulti.cpp
+++ b/libraries/WiFi/src/WiFiMulti.cpp
@@ -160,6 +160,8 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
             log_i("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb);
 
             WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID);
+            if (ipv6_support == true)
+                WiFi.IPv6(true);
             status = WiFi.status();
 
             auto startTime = millis();
@@ -202,3 +204,7 @@ uint8_t WiFiMulti::run(uint32_t connectTimeout)
 
     return status;
 }
+
+void WiFiMulti::IPv6(bool state) {
+    ipv6_support = state;
+}
diff --git a/libraries/WiFi/src/WiFiMulti.h b/libraries/WiFi/src/WiFiMulti.h
index 38ddb5d9f95..bbeb78dc860 100644
--- a/libraries/WiFi/src/WiFiMulti.h
+++ b/libraries/WiFi/src/WiFiMulti.h
@@ -42,10 +42,12 @@ class WiFiMulti
 
     bool addAP(const char* ssid, const char *passphrase = NULL);
 
+    void IPv6(bool state);
     uint8_t run(uint32_t connectTimeout=5000);
 
 private:
     std::vector<WifiAPlist_t> APlist;
+    bool ipv6_support;
 };
 
 #endif /* WIFICLIENTMULTI_H_ */
diff --git a/libraries/WiFi/src/WiFiSTA.cpp b/libraries/WiFi/src/WiFiSTA.cpp
index 7734f5d79b5..dc8ff8ee6bc 100644
--- a/libraries/WiFi/src/WiFiSTA.cpp
+++ b/libraries/WiFi/src/WiFiSTA.cpp
@@ -726,6 +726,19 @@ bool WiFiSTAClass::enableIpV6()
     return esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_WIFI_STA)) == ESP_OK;
 }
 
+/**
+ * Enable IPv6 support on the station interface.
+ * @return true on success
+ */
+bool WiFiSTAClass::IPv6(bool state)
+{
+   if (state)
+       WiFiGenericClass::setStatusBits(WIFI_WANT_IP6_BIT);
+   else
+       WiFiGenericClass::clearStatusBits(WIFI_WANT_IP6_BIT);
+   return true;
+}
+
 /**
  * Get the station interface IPv6 address.
  * @return IPv6Address
diff --git a/libraries/WiFi/src/WiFiSTA.h b/libraries/WiFi/src/WiFiSTA.h
index b8bb855c198..6892c996b30 100644
--- a/libraries/WiFi/src/WiFiSTA.h
+++ b/libraries/WiFi/src/WiFiSTA.h
@@ -84,6 +84,7 @@ class WiFiSTAClass
     uint8_t subnetCIDR();
     
     bool enableIpV6();
+    bool IPv6(bool state);
     IPv6Address localIPv6();
 
     // STA WiFi info
diff --git a/libraries/WiFi/src/WiFiServer.cpp b/libraries/WiFi/src/WiFiServer.cpp
index db21858125b..03e3c797e83 100644
--- a/libraries/WiFi/src/WiFiServer.cpp
+++ b/libraries/WiFi/src/WiFiServer.cpp
@@ -47,8 +47,8 @@ WiFiClient WiFiServer::available(){
     _accepted_sockfd = -1;
   }
   else {
-  struct sockaddr_in _client;
-  int cs = sizeof(struct sockaddr_in);
+  struct sockaddr_in6 _client;
+  int cs = sizeof(struct sockaddr_in6);
 #ifdef ESP_IDF_VERSION_MAJOR
     client_sock = lwip_accept(sockfd, (struct sockaddr *)&_client, (socklen_t*)&cs);
 #else
@@ -76,14 +76,14 @@ void WiFiServer::begin(uint16_t port, int enable){
   if(port){
       _port = port;
   }
-  struct sockaddr_in server;
-  sockfd = socket(AF_INET , SOCK_STREAM, 0);
+  struct sockaddr_in6 server;
+  sockfd = socket(AF_INET6 , SOCK_STREAM, 0);
   if (sockfd < 0)
     return;
   setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
-  server.sin_family = AF_INET;
-  server.sin_addr.s_addr = _addr;
-  server.sin_port = htons(_port);
+  server.sin6_family = AF_INET6;
+  server.sin6_addr = _addr;
+  server.sin6_port = htons(_port);
   if(bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
     return;
   if(listen(sockfd , _max_clients) < 0)
@@ -106,8 +106,8 @@ bool WiFiServer::hasClient() {
     if (_accepted_sockfd >= 0) {
       return true;
     }
-    struct sockaddr_in _client;
-    int cs = sizeof(struct sockaddr_in);
+    struct sockaddr_in6 _client;
+    int cs = sizeof(struct sockaddr_in6);
 #ifdef ESP_IDF_VERSION_MAJOR
     _accepted_sockfd = lwip_accept(sockfd, (struct sockaddr *)&_client, (socklen_t*)&cs);
 #else
diff --git a/libraries/WiFi/src/WiFiServer.h b/libraries/WiFi/src/WiFiServer.h
index 346986abad5..d516e5502d2 100644
--- a/libraries/WiFi/src/WiFiServer.h
+++ b/libraries/WiFi/src/WiFiServer.h
@@ -23,12 +23,14 @@
 #include "Server.h"
 #include "WiFiClient.h"
 #include "IPAddress.h"
+#include "lwip/inet.h"
+#include "lwip/netdb.h"
 
 class WiFiServer : public Server {
   private:
     int sockfd;
     int _accepted_sockfd = -1;
-    IPAddress _addr;
+    in6_addr _addr;
     uint16_t _port;
     uint8_t _max_clients;
     bool _listening;
@@ -37,12 +39,19 @@ class WiFiServer : public Server {
   public:
     void listenOnLocalhost(){}
 
-    // _addr(INADDR_ANY) is the same as _addr() ==> 0.0.0.0
-    WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
+    WiFiServer(uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
       log_v("WiFiServer::WiFiServer(port=%d, ...)", port);
+      _addr = IN6ADDR_ANY_INIT;
     }
-    WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_addr(addr),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
+    WiFiServer(const IPAddress& addr, uint16_t port=80, uint8_t max_clients=4):sockfd(-1),_accepted_sockfd(-1),_port(port),_max_clients(max_clients),_listening(false),_noDelay(false) {
       log_v("WiFiServer::WiFiServer(addr=%s, port=%d, ...)", addr.toString().c_str(), port);
+      char buffer[64] = { 0 };
+      // Print IPv4 in IPv6 notation
+      sprintf(buffer, "::FFFF:%s", addr.toString().c_str());
+      int rc = inet_pton(AF_INET6, buffer, &_addr);
+      if (rc != 1) {
+        log_e("WiFiServer::WiFiServer unable to resolve address, rc=%d", rc);
+      }
     }
     ~WiFiServer(){ end();}
     WiFiClient available();
diff --git a/libraries/WiFiClientSecure/src/ssl_client.cpp b/libraries/WiFiClientSecure/src/ssl_client.cpp
index 6ab9b10570d..92d429e2669 100644
--- a/libraries/WiFiClientSecure/src/ssl_client.cpp
+++ b/libraries/WiFiClientSecure/src/ssl_client.cpp
@@ -60,6 +60,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
     int ret, flags;
     int enable = 1;
     log_v("Free internal heap before TLS %u", ESP.getFreeHeap());
+    bool is_ipv4 = true;
 
     if (rootCABuff == NULL && pskIdent == NULL && psKey == NULL && !insecure && !useRootCABundle) {
         return -1;
@@ -67,24 +68,45 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
 
     log_v("Starting socket");
     ssl_client->socket = -1;
+    struct sockaddr_storage serveraddr;
+    ip_addr_t dstip;
+    IPAddress srv((uint32_t)0);
+
+    if (WiFiGenericClass::getStatusBits() & WIFI_WANT_IP6_BIT) {
+        ip_addr_t srv6;
+        if(!WiFiGenericClass::hostByName6(host, srv6)){
+            return -1;
+        }
+        if (IP_IS_V6(&srv6)) {
+            is_ipv4 = false;
+            ssl_client->socket = lwip_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+            struct sockaddr_in6 *tmpaddr = (struct sockaddr_in6 *)&serveraddr;
+            memset((char *) tmpaddr, 0, sizeof(struct sockaddr_in6));
+            tmpaddr->sin6_family = AF_INET6;
+            inet6_addr_from_ip6addr(&tmpaddr->sin6_addr, ip_2_ip6(&srv6));
+            tmpaddr->sin6_port = htons(port);
+        } else {
+            srv = ip4_addr_get_u32(&srv6.u_addr.ip4);
+        }
+    } else {
+        if(!WiFiGenericClass::hostByName(host, srv))
+            return -1;
+    }
+    if (is_ipv4 == true) {
+        ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+        struct sockaddr_in *serv_addr = (struct sockaddr_in*)&serveraddr;
+        memset(serv_addr, 0, sizeof(serv_addr));
+        serv_addr->sin_family = AF_INET;
+        serv_addr->sin_addr.s_addr = srv;
+        serv_addr->sin_port = htons(port);
+    }
 
-    ssl_client->socket = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (ssl_client->socket < 0) {
         log_e("ERROR opening socket");
         return ssl_client->socket;
     }
 
-    IPAddress srv((uint32_t)0);
-    if(!WiFiGenericClass::hostByName(host, srv)){
-        return -1;
-    }
-
     fcntl( ssl_client->socket, F_SETFL, fcntl( ssl_client->socket, F_GETFL, 0 ) | O_NONBLOCK );
-    struct sockaddr_in serv_addr;
-    memset(&serv_addr, 0, sizeof(serv_addr));
-    serv_addr.sin_family = AF_INET;
-    serv_addr.sin_addr.s_addr = srv;
-    serv_addr.sin_port = htons(port);
 
     if(timeout <= 0){
         timeout = 30000; // Milli seconds.
@@ -97,7 +119,7 @@ int start_ssl_client(sslclient_context *ssl_client, const char *host, uint32_t p
     tv.tv_sec = timeout / 1000;
     tv.tv_usec = (timeout % 1000) * 1000;
 
-    int res = lwip_connect(ssl_client->socket, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
+    int res = lwip_connect(ssl_client->socket, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
     if (res < 0 && errno != EINPROGRESS) {
         log_e("connect on fd %d, errno: %d, \"%s\"", ssl_client->socket, errno, strerror(errno));
         close(ssl_client->socket);