Linux: Binds to MY_IP_ADDRESS in client mode (#849)

This commit is contained in:
Marcelo Aquino
2017-05-21 14:27:22 +02:00
committed by Olivier
parent abba1ec377
commit fb3d936d4c
5 changed files with 45 additions and 10 deletions
+3
View File
@@ -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
+1 -1
View File
@@ -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
+30 -8
View File
@@ -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;
+6 -1
View File
@@ -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
+5
View File
@@ -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;