I have simple DNS resolve demo in my ESP8266. Can't find why it cat resolve Ubuntu virtual machine on AWS. According to my understanding DNS server is my home router 192.168.1.1. Resolution works fine from my desktop PC while ESP8266 fails. Why and how to fix that?
void printDNSServers() {
Serial.print("DNS #1, #2 IP: ");
WiFi.dnsIP().printTo(Serial);
Serial.print(", ");
WiFi.dnsIP(1).printTo(Serial);
Serial.println();
}
void printIPAddressOfHost(const char* host) {
IPAddress resolvedIP;
if (!WiFi.hostByName(host, resolvedIP)) {
DEBUG_LOG("DNS lookup failed. ");
DEBUG_LOGLN(host);
}
DEBUG_LOGLN(host);
DEBUG_LOGLN(" IP: ");
Serial.println(resolvedIP);
}
void loop()
{
printDNSServers();
printIPAddressOfHost("yahoo.com");
printIPAddressOfHost("ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port");
}
Output is:
DNS #1, #2 IP: 192.168.1.1, (IP unset)
yahoo.com
IP:
98.138.219.232
DNS lookup failed. ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
IP:
You are trying to resolve the following hostname:
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com port
You need to take the port off the end, as the current string is not a valid hostname.
ec2-34-254-225-201.eu-west-1.compute.amazonaws.com
Related
I am looking for a way to get the device IP that is not based on Wifi. I am unable to find the local IP of the current device when compiling to Linux app running on an ethernet connection with no wifi card.
I tried using 'package:wifi/wifi.dart' and 'package:network_info_plus/network_info_plus.dart' to get the device's local ip and both packages gave this error: MissingPluginException (MissingPluginException(No implementation found for method ip on channel plugins.ly.com/wifi))
Is there a way to get the device local IP without a Wifi card?
UPDATE:
Using https://stackoverflow.com/a/52411510/5861729 and https://stackoverflow.com/a/43803986/16477035 I was able to figure out a clean way to get my local ip.
// Find localIp
String localIp = '';
final List<String> privateNetworkMasks = ['10', '172.16', '192.168'];
for (var interface in await NetworkInterface.list()) {
for (var addr in interface.addresses) {
for (final possibleMask in privateNetworkMasks) {
if (addr.address.startsWith(possibleMask)) {
localIp = addr.address;
break;
}
}
}
}
Run 'flutter clean' then 'flutter pub get' and re install your app
Below is the code from server file. Trying to get the remoteAdress as host name. but it is giving Remote Address received: :ffff :10.197.0.145 instead of hostname.
async function serverImpl(stream) {
const ctx = {
id: crypto.createHash("sha256").update(stream.getSession())
.digest("hex"), // deriving a unique client id from the tls session identifier
remoteAddress: stream.remoteAddress,
remotePort: stream.remotePort,
servername: stream.servername
}
}
We are using TLS handshake for the Security. Expecting hostname from TCP or using TLS mandatorily. Help us on this
I need to make a simple GET call using HTTP. Despite successfully connecting to the WiFi network, getting the IP, Gateway and DNS correctly, The HTTP client keeps getting connection failed error. I tried using the WiFi client as well but no luck. It don't think the issue is with my code, I tried to use the code from the examples folder as well and it fails too. I tried connecting to a local internal server and it failed. I have spent about a whole day on this and I can't figure what could be wrong.
The code is given below. That is all there is at the moment.
I am using the Arduino for ESPRESSIF on Platform IO using Visual Code Editor on Windows.
The WifiConnect function is called from setup()
Initially I was only calling the WiFi.begin() function to connect which was also connecting with the WiFi but since the connection kept failing I tried ESP8266WiFiMulti as per the sample code.
I even checked that host name resolution also works
IPAddress remote_addr;
WiFi.hostByName("192.168.2.107", remote_addr);
Serial.println(remote_addr);
But connecting to any server always fails. I've tried connecting to servers internal to the network, servers on the internet, servers running http on special ports, normal port 80 etc. But it stubbornly refuses to connect.
#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include "Ticker.h"
#include <WiFiClient.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
void WifiConnect()
{
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("MySSID", "MySECret Password");
Serial.print("Connecting");
while (WiFiMulti.run() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println();
Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
Serial.println(WiFi.dnsIP());
Serial.println(WiFi.gatewayIP());
Serial1.println(WiFi.localIP());
}
void logToThinkSpeakt(){
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
HTTPClient http;
Serial.print("[HTTP] begin...\n");
if (http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html")) { // HTTP
Serial.print("[HTTP] GET...\n");
// start connection and send HTTP header
int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();
Serial.println(payload);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.printf("[HTTP} Unable to connect\n");
}
}
}
PLATFORM: Espressif 8266 2.6.2 > NodeMCU 1.0 (ESP-12E Module)
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
PACKAGES:
framework-arduinoespressif8266 3.20704.0 (2.7.4)
tool-esptool 1.413.0 (4.13)
tool-esptoolpy 1.20800.0 (2.8.0)
tool-mklittlefs 1.203.200522 (2.3)
tool-mkspiffs 1.200.0 (2.0)
toolchain-xtensa 2.40802.200502 (4.8.2)
LDF: Library Dependency Finder
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 29 compatible libraries
Scanning dependencies...
Dependency Graph
|-- 1.0
|-- 1.2
| |-- 1.0
|-- 1.0
Building in release mode
I see following behavior with sendmsg in case of IPv4:
Suppose that 10.1.2.3 is the client IP.
And 10.1.2.10 is configured on one of the interfaces of client.
In an UDP message, following control information is added into the packet:
It is just the source-address or interface address that server should use in replying back to the client:
cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(sa->sin_addr);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR_WITH_ERROR;
* (struct in_addr *)CMSG_DATA(cmsg) = sa->sin_addr;
cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));
And message is sent as:
sendmsg(fd, send_msg, 0);
If I configure 10.1.2.10 as source-ip and once it is added into cmsg, things work fine.
server replies back to 10.1.2.10.
But, if I configure some un-reachable IP address or IP that is not configured on any interface on the client, sendmsg fails with below error:
sendmsg to 10.1.2.3(10.1.2.3).1813 failed: Can't assign
requested address
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
But I do not see the same behavior with IPv6:
Suppose that 2001::1 is the client IP.
And 2001::2001 is configured on one of the interfaces of client.
IPv6 source address is added into control message as below:
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_PKTINFO;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
memcpy((struct in6_addr *)CMSG_DATA(cmsg), &(sa6->sin6_addr),
sizeof(sa6->sin6_addr));
cmsg = (struct cmsghdr *)((caddr_t) cmsg + ALIGN(cmsg->cmsg_len));
It works fine, if I configure 2001::2001 as source-ip and server does reply back to this address.
But If I configure an unreachable IPv6 source address say 1001::1001, there is no error message from sendmsg similar to the one we see in IPv4 case. Message is still sent with original IPv6 which is 2001::1.
Can someone please suggest on what can be the problem?
Thanks.
IP_SENDSRCADDR and IPV6_PKTINFO must be two different implementations. Maybe in the first case it just control errors. Have you tried to set the interface index in the ancillary data for IPV6_PKTINFO? For IPV6_PKTINFO the ancillary data is of type: in6_pktinfo.
struct in6_pktinfo {
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
unsigned int ipi6_ifindex; /* send/recv if index */
};
Hope this helps in some way
I meet the same issue, I set source address as 408:6666:f:f500::1 (not local IP), but I received the packet with 4085:6666:f:fc10::1 (the local IP) as source address, no matter I set ipi6_ifindex or not.
I will get forward to investigate it.
I am trying to develop a Video Client/functionality that captures video using webcam and transfers to other servent (server-client) somewhere on the internet. I am using UDPCLient Class to do that.
I want my application to be able to listen and tarnsmit video captured from webcam. The capturing, transmission and receiving works fine when i do that on local network.
But when i test the application from behind router (across two differnt networks/internet) after forwarding respective ports, the internet connectivity is lost on both routers (They hang up or something) and i need to restart the routers or switch to an alternate connection. The configuration is as follows:
Servent 1 <--> Router1 <--> Internet Connection#01
Servent 02 <---> Router2 <---> Internet Connection#02
Both connections are on separate DSL Line. One of the routers is ZTE brand and the other is of Netgear.
Code for listenning/transmission is as follows:
private void StartSockets()
{
//For testing across internet i use IPAddress obtained via different function
var IPAddress = getMyIpAddress();
this.udpSender = new UdpClient(IpAddress, 4000);
this.udpListener = new UdpClient(4000);
}
private IPAddress getMyIpAddress()
{
IPAddress localIP ;//= AddressAr[0];
localIP = IPAddress.Parse(GetPublicIP());
return localIP;
}
public string GetPublicIP()
{
String direction = "";
WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
using (WebResponse response = request.GetResponse())
{
using (StreamReader stream = new StreamReader(response.GetResponseStream()))
{
direction = stream.ReadToEnd();
}
}
//Search for the ip in the html
int first = direction.IndexOf("Address: ") + 9;
int last = direction.LastIndexOf("</body>");
direction = direction.Substring(first, last - first);
return direction;
}
Code for receiving response is as follows:
private void ReceiveData()
{
//For testing across internet i use IPAddress obtained via different function
var IPAddress = getMyIpAddress();
IPEndPoint ep = new IPEndPoint(IPAddress, myPort);
try
{
byte[] receiveBytes = this.udpListener.Receive(ref ep);
this.OnReadImage(new ImageEventArgs(this.ByteToImage(receiveBytes)));
}
catch (Exception)
{
}
}
If i test on local network , i use DNSHostname to get ip address (private ip addresses) and video works fine on local network. That does not work over internet so i switch to live Ip Address and thus i use the method of getPublicIpAddress().
I know there is something seriously wrong with my approach? What would be right approach?
Should i switch to TCP Listenner? I intend to have multiple receiver of same video in future. So would that affect?
Can UDP clients cause routers to crash, hang up and restart? How can i avoid that?
Lastly, if were to avoid port-forwarding what would be the best strategy?
Please help.
Thanks
Steve