Linux: Binds to MY_IP_ADDRESS in client mode (#849)
This commit is contained in:
@@ -138,6 +138,9 @@ bool gatewayTransportInit(void)
|
||||
#endif /* MY_GATEWAY_ESP8266 */
|
||||
|
||||
#if defined(MY_GATEWAY_CLIENT_MODE)
|
||||
#if defined(MY_GATEWAY_LINUX) && defined(MY_IP_ADDRESS)
|
||||
client.bind(_ethernetGatewayIP);
|
||||
#endif
|
||||
#if defined(MY_CONTROLLER_URL_ADDRESS)
|
||||
if (client.connect(MY_CONTROLLER_URL_ADDRESS, MY_PORT)) {
|
||||
#else
|
||||
|
||||
@@ -105,7 +105,7 @@ bool gatewayTransportConnect(void)
|
||||
MY_SERIALDEVICE.println(WiFi.localIP());
|
||||
#elif defined(MY_GATEWAY_LINUX)
|
||||
#if defined(MY_IP_ADDRESS)
|
||||
//TODO
|
||||
_MQTT_ethClient.bind(_MQTT_clientIp);
|
||||
#endif
|
||||
#else
|
||||
#ifdef MY_IP_ADDRESS
|
||||
|
||||
@@ -43,11 +43,13 @@ EthernetClient::EthernetClient(int sock) : _sock(sock)
|
||||
|
||||
int EthernetClient::connect(const char* host, uint16_t port)
|
||||
{
|
||||
int sockfd;
|
||||
struct addrinfo hints, *servinfo, *p;
|
||||
struct addrinfo hints, *servinfo, *localinfo, *p;
|
||||
int rv;
|
||||
char s[INET6_ADDRSTRLEN];
|
||||
char port_str[6];
|
||||
bool use_bind = (_srcip != 0);
|
||||
|
||||
close();
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
@@ -58,17 +60,31 @@ int EthernetClient::connect(const char* host, uint16_t port)
|
||||
logError("getaddrinfo: %s\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
if (use_bind) {
|
||||
if ((rv = getaddrinfo(_srcip.toString().c_str(), port_str, &hints, &localinfo)) != 0) {
|
||||
logError("getaddrinfo: %s\n", gai_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// loop through all the results and connect to the first we can
|
||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||
if ((sockfd = socket(p->ai_family, p->ai_socktype,
|
||||
p->ai_protocol)) == -1) {
|
||||
if ((_sock = socket(p->ai_family, p->ai_socktype,
|
||||
p->ai_protocol)) == -1) {
|
||||
logError("socket: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (::connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
|
||||
::close(sockfd);
|
||||
if (use_bind) {
|
||||
if (::bind(_sock, localinfo->ai_addr, localinfo->ai_addrlen) == -1) {
|
||||
close();
|
||||
logError("bind: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (::connect(_sock, p->ai_addr, p->ai_addrlen) == -1) {
|
||||
close();
|
||||
logError("connect: %s\n", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
@@ -81,13 +97,14 @@ int EthernetClient::connect(const char* host, uint16_t port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
_sock = sockfd;
|
||||
|
||||
void *addr = &(((struct sockaddr_in*)p->ai_addr)->sin_addr);
|
||||
inet_ntop(p->ai_family, addr, s, sizeof s);
|
||||
logDebug("connected to %s\n", s);
|
||||
|
||||
freeaddrinfo(servinfo); // all done with this structure
|
||||
if (use_bind) {
|
||||
freeaddrinfo(localinfo); // all done with this structure
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -273,6 +290,11 @@ void EthernetClient::close()
|
||||
}
|
||||
}
|
||||
|
||||
void EthernetClient::bind(IPAddress ip)
|
||||
{
|
||||
_srcip = ip;
|
||||
}
|
||||
|
||||
int EthernetClient::getSocketNumber()
|
||||
{
|
||||
return _sock;
|
||||
|
||||
@@ -155,6 +155,10 @@ public:
|
||||
* @brief Close the connection.
|
||||
*/
|
||||
void close();
|
||||
/**
|
||||
* @brief Bind the conection to the specified local ip.
|
||||
*/
|
||||
void bind(IPAddress ip);
|
||||
/**
|
||||
* @brief Get the internal socket file descriptor.
|
||||
*
|
||||
@@ -200,7 +204,8 @@ public:
|
||||
friend class EthernetServer;
|
||||
|
||||
private:
|
||||
int _sock; //!< @brief Network socket.
|
||||
int _sock; //!< @brief Network socket file descriptor.
|
||||
IPAddress _srcip; //!< @brief Local ip to bind to.
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -51,6 +51,11 @@ void EthernetServer::begin(IPAddress address)
|
||||
char ipstr[INET_ADDRSTRLEN];
|
||||
char portstr[6];
|
||||
|
||||
if (sockfd != -1) {
|
||||
close(sockfd);
|
||||
sockfd = -1;
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
Reference in New Issue
Block a user