Skip to content
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

WiFiClientSecure not working lwip mode ! (insecure) #8291

Closed
elexal opened this issue Aug 24, 2021 · 9 comments
Closed

WiFiClientSecure not working lwip mode ! (insecure) #8291

elexal opened this issue Aug 24, 2021 · 9 comments

Comments

@elexal
Copy link

elexal commented Aug 24, 2021

hello friend
we have an ESP8266 that connects to the host SSL with wifi
And we receive data from it without any problems
We have an interface Ethernet(W5500 or Enc28j60) which we want to receive data from it
If the SSL does not exist it connects to the server and receives the data with wificlient and lwip library
When we activate Setinsecure and WiFiClientSecure it doesn’t connect to the server anymore.
The server that we want to connect to by Ethernet has SSL and we have to use wificlient secure library that works without any problem on wifi , but on Ethernet mode it doesn’t connect
Codes for wifi and Ethernet are the same and are used from one library
In the following example we connect to a host by Ethernet and receive data but if we change the library from wifi client to wificlient secure it doesn’t work anymore.
`/*
This sketch establishes a TCP connection to a "quote of the day" service.
It sends a "hello" message, and then prints received data.
*/

#include <SPI.h>
#include <ENC28J60lwIP.h>

#include <ESP8266WiFi.h>

const char* host = "djxmmx.net";
const uint16_t port = 17;

#define CSPIN D1

ENC28J60lwIP eth(CSPIN);

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

IPAddress server(23, 28, 179, 206);

void setup() {
Serial.begin(115200);
delay(500);

WiFi.mode(WIFI_OFF);

SPI.begin();
// if (!eth.config(ip, gw, nm, gw, IPADDR_NONE)) {
// Serial.println("wrong config");
// }
eth.setDefault(); // use ethernet for default route
if (!eth.begin(mac)) {
Serial.println("ethernet hardware not found ... sleeping");
while (1) {
delay(1000);
}
} else {
Serial.print("connecting ethernet");
while (!eth.connected()) {
Serial.print(".");
delay(1000);
}
}
Serial.println();
Serial.print("ethernet IP address: ");
Serial.println(eth.localIP());
Serial.println(eth.gatewayIP());
Serial.println(eth.subnetMask());
Serial.println(WiFi.dnsIP());
}

void loop() {
static bool wait = true;

Serial.print("connecting to ");
Serial.print(host);
Serial.print(':');
Serial.println(port);

WiFiClient client;
if (!client.connect(host, port)) {
Serial.println("connection failed");
delay(5000);
return;
}

// This will send a string to the server
Serial.println("sending data to server");
if (client.connected()) {
client.println("hello from ESP8266");
}

// wait for data to be available
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
delay(60000);
return;
}
}

// Read all the lines of the reply from server and print them to Serial
Serial.println("receiving from remote server");
// not testing 'client.connected()' since we do not need to send data here
while (client.available()) {
char ch = static_cast(client.read());
Serial.print(ch);
}

// Close the connection
Serial.println();
Serial.println("closing connection");
client.stop();

if (wait) {
delay(300000); // execute once every 5 minutes, don't flood remote service
}
wait = true;
}`

@JAndrassy
Copy link
Contributor

the service at djxmmx.net:17 doesn't support secure connection. use some https site for the test

@elexal
Copy link
Author

elexal commented Aug 24, 2021

i Want to read this link :
https://assess.mmaviot.com/gadget/skeleton?serial=swr012108031138&uid=95f916e0-56d6-487f-82dd-da75b14081cb

My Code :
WiFi connection :

//        WiFi.begin(ssid, pass);
//        SPI.begin();
//        while (WiFi.status() != WL_CONNECTED)
//        {
//          delay(500);
//          Serial.print(".");
//        }
//        Serial.println();
//  
//        Serial.print("Connected, IP address: ");
//        Serial.println(WiFi.localIP());

Ethernet Connection :

  eth.setDefault(); // use ethernet for default route
  if (!eth.begin(mac)) {
    Serial.println("ethernet hardware not found ... sleeping");
    while (1) {
      delay(1000);
    }
  } else {
    Serial.print("connecting ethernet");
    while (!eth.connected()) {
      Serial.print(".");
      delay(1000);
    }
  }

Main Code :

#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <FS.h>
#include "ESP8266httpUpdate.h"
#include <ENC28J60lwIP.h>
//#include <W5500lwIP.h>
#define CSPIN 15
//Wiznet5500lwIP eth(CSPIN);
ENC28J60lwIP eth(CSPIN);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(23, 28, 179, 206);
class TLSClass {
  public:
    boolean TLS_Call(String command_get);
    String AnsTLS = "";
    String PrivateKey = "";
};
boolean TLSClass::TLS_Call(String command_get) {
  boolean TLS = false;
  //  WiFi.mode(WIFI_OFF);
  static bool wait = true;
  Serial.print("connecting to ");
  Serial.print("assess.mmaviot.com");
  Serial.print(':');
  Serial.println("443");
  //WiFiClient client;
  WiFiClientSecure client;
  client.setTimeout(5000);
  client.setInsecure();
  if (client.connect("assess.mmaviot.com", 443)) {
    Serial.println("connected to host");
    client.print( String("GET ") + command_get + " HTTP/1.1\r\n" + "Host: " + "assess.mmaviot.com" + "\r\n" + "Connection: close" + "\r\n\r\n");
    Serial.println("request sent");
    Serial.flush();
    char status[20] = {0};
    client.readBytesUntil('\r', status, sizeof(status));
    if (strcmp(status, "HTTP/1.1 200 OK") == 0)
    {
      Serial.println("Connection Success");
      TLS = true;
      while (client.connected()) {
        char endOfHeaders[] = "\r\n\r\n";
        if (client.find(endOfHeaders)) {
          Serial.println(status);
          String Data_Server = client.readString();
          AnsTLS = Data_Server;
          Serial.println(Data_Server);
        }
      }
    }
    else {
      Serial.println("** Connection Failed **");
      Serial.println(status);
    }
    Serial.println("receiving from remote server");
    // not testing 'client.connected()' since we do not need to send data here
    Serial.println("Print Data Available");
    while (client.available()) {
      char ch = static_cast<char>(client.read());
      Serial.print(ch);
    }
    Serial.println("closing connection");
    client.stop();
    client.flush();
  }
  else
  {
    TLS = false;
    Serial.println("***********************");
    Serial.println("** Connection Failed **");
    Serial.println("***********************");
    delay(3000);
  }
  return TLS;
}

Result =>>
Over Radio : (it ok , & give 200 OK )

........
Connected, IP address: 192.168.1.107
-----------------------------------------
connecting to assess.mmaviot.com:443
connected to host
request sent
Connection Success
HTTP/1.1 200 OK
"a1d4f093527e7e7287984a38c2ee7514cb2f3f69d7cd972af65a92f7fd7bc98111e9165bd900804a06f0d7af47c9890db375a266013e8ce59f398f71c62b8e6345e752bc4bc1a5b44d57e5996c4fb49a224aa51a2a4043dee24b277be5c8a5190498ef05a9c3e35a049a9def399ab9bad83a42abb4320169132db015e1919acd547823d5e98e368d1b60ff6524ff93d4df55b32a757d7f36a8f5562f179cfb71ca1a3882593fe20a75c04dae513817d60437a81b5430682455718898f2b903d53af1c2103ab0b914320fcb090276886e"
receiving from remote server
Print Data Available
closing connection
Skeleton Data
Skelete : True !!!

Overt Ethernet Cable :

connecting ethernet...
ethernet IP address: 192.168.1.105
192.168.1.1
255.255.255.0
-----------------------------------------
connecting to assess.mmaviot.com:443
***********************
** Connection Failed **
***********************
Skelete : False
-----------------------------------------
connecting to assess.mmaviot.com:443
***********************
** Connection Failed **
***********************
Skelete : False
-----------------------------------------
connecting to assess.mmaviot.com:443
***********************
** Connection Failed **
***********************
Skelete : False
-----------------------------------------
connecting to assess.mmaviot.com:443
***********************
** Connection Failed **
***********************
Skelete : False
-----------------------------------------
connecting to assess.mmaviot.com:443
***********************
** Connection Failed **
***********************

I just change the connection type
over radio all ok , over ethernet connection faild (WiFiClientSecure)

@elexal
Copy link
Author

elexal commented Aug 25, 2021

Do you have any comments?

@JerryLoveCat

This comment has been minimized.

@mousecat98
Copy link

mousecat98 commented Sep 6, 2021

Hello @elexal,
I am also using the lwIP-stack and a W5500 Ethernet shield with an ESP8266. In my case, I was also not able to get a connection to one of my servers using the WiFiClientSecure class whereas the same code works with the WiFiClient class.

Digging a bit deeper into the matter and debugging with the additional debug flags -DDEBUG_ESP_WIFI and -DDEBUG_ESP_HTTP_CLIENT I found out that the DNS name resolution seems to fail as follows:

[hostByName] request IP for: host.xyz
[hostByName] Host: host.xyz lookup error: -5!

However, I currently use the following as a temporary workaround (before each .connect()-call of the WiFiClientSecure):

// WORKAROUND for failing DNS-queries
WiFiClient wifi_test;
wifi_test.connect("host.xyz", 3000);
wifi_test.stop();

It should query the IP from the DNS server and cache it so that the name resolution won't fail. This has worked fine so far for me. However, I haven't done much testing.

Maybe someone else could double-check the described behavior and workaround.
Also see: #8120

@MassiPi
Copy link

MassiPi commented Sep 10, 2021

Dns error -5 with W5500 module.. give a look here #6212 :)
there is a fix for ESP8266WiFiGeneric.cpp you can apply until the bug is fixed (expected in 3.1)

@d-a-v
Copy link
Collaborator

d-a-v commented Sep 21, 2021

Can you try with this PR #8317 ?

@mousecat98
Copy link

Works as intended :)

mcspr pushed a commit that referenced this issue Oct 16, 2021
esp_yield() now also calls esp_schedule(), original esp_yield() function renamed to esp_suspend().

Don't use delay(0) in the Core internals, libraries and examples. Use yield() when the code is
supposed to be called from CONT, use esp_yield() when the code can be called from either CONT or SYS.
Clean-up esp_yield() and esp_schedule() declarations across the code and use coredecls.h instead.

Implement helper functions for libraries that were previously using esp_yield(), esp_schedule() and
esp_delay() directly to wait for certain SYS context tasks to complete. Correctly use esp_delay()
for timeouts, make sure scheduled functions have a chance to run (e.g. LwIP_Ethernet uses recurrent)

Related issues:
- #6107 - discussion about the esp_yield() and esp_delay() usage in ClientContext
- #6212 - discussion about replacing delay() with a blocking loop
- #6680 - pull request introducing LwIP-based Ethernet
- #7146 - discussion that originated UART code changes
- #7969 - proposal to remove delay(0) from the example code
- #8291 - discussion related to the run_scheduled_recurrent_functions() usage in LwIP Ethernet
- #8317 - yieldUntil() implementation, similar to the esp_delay() overload with a timeout and a 0 interval
@mcspr
Copy link
Collaborator

mcspr commented Oct 19, 2021

Closing via #7148 as well

@mcspr mcspr closed this as completed Oct 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants