Skip to content

Instantly share code, notes, and snippets.

@shimarin
Last active April 11, 2022 12:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shimarin/90a83be3da4d04b4e7f44d7302f310b3 to your computer and use it in GitHub Desktop.
Save shimarin/90a83be3da4d04b4e7f44d7302f310b3 to your computer and use it in GitHub Desktop.
diff --git a/components/tcp_transport/transport_tcp.c b/components/tcp_transport/transport_tcp.c
index 5bfb99dd..cdae5bf0 100644
--- a/components/tcp_transport/transport_tcp.c
+++ b/components/tcp_transport/transport_tcp.c
@@ -32,60 +32,51 @@ typedef struct {
int sock;
} transport_tcp_t;
-static int resolve_dns(const char *host, struct sockaddr_in *ip) {
-
- struct hostent *he;
- struct in_addr **addr_list;
- he = gethostbyname(host);
- if (he == NULL) {
- return ESP_FAIL;
- }
- addr_list = (struct in_addr **)he->h_addr_list;
- if (addr_list[0] == NULL) {
- return ESP_FAIL;
- }
- ip->sin_family = AF_INET;
- memcpy(&ip->sin_addr, addr_list[0], sizeof(ip->sin_addr));
- return ESP_OK;
-}
-
static int tcp_connect(esp_transport_handle_t t, const char *host, int port, int timeout_ms)
{
- struct sockaddr_in remote_ip;
+ struct addrinfo* addr;
+ struct addrinfo hints;
struct timeval tv = { 0 };
transport_tcp_t *tcp = esp_transport_get_context_data(t);
- bzero(&remote_ip, sizeof(struct sockaddr_in));
-
- //if stream_host is not ip address, resolve it AF_INET,servername,&serveraddr.sin_addr
- if (inet_pton(AF_INET, host, &remote_ip.sin_addr) != 1) {
- if (resolve_dns(host, &remote_ip) < 0) {
- return -1;
- }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = AF_UNSPEC;
+ char buf[6];
+ sprintf(buf, "%d", port);
+ if (getaddrinfo(host, buf, &hints, &addr) != 0) {
+ ESP_LOGE(TAG, "Error getaddrinfo()");
+ return -1;
}
- tcp->sock = socket(PF_INET, SOCK_STREAM, 0);
+ tcp->sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
if (tcp->sock < 0) {
ESP_LOGE(TAG, "Error create socket");
return -1;
}
- remote_ip.sin_family = AF_INET;
- remote_ip.sin_port = htons(port);
-
esp_transport_utils_ms_to_timeval(timeout_ms, &tv); // if timeout=-1, tv is unchanged, 0, i.e. waits forever
setsockopt(tcp->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(tcp->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
- ESP_LOGD(TAG, "[sock=%d],connecting to server IP:%s,Port:%d...",
- tcp->sock, ipaddr_ntoa((const ip_addr_t*)&remote_ip.sin_addr.s_addr), port);
- if (connect(tcp->sock, (struct sockaddr *)(&remote_ip), sizeof(struct sockaddr)) != 0) {
+#if LWIP_IPV6
+ if (addr->ai_family == AF_INET6) {
+ struct sockaddr_in6* addr6 = (struct sockaddr_in6*)addr->ai_addr;
+ if (addr6->sin6_addr.s6_addr[0] == 0xfe && addr6->sin6_addr.s6_addr[1] == 0x80) { // link local
+ addr6->sin6_scope_id = 2;
+ }
+ }
+#endif
+
+ if (connect(tcp->sock, addr->ai_addr, addr->ai_addrlen) != 0) {
close(tcp->sock);
tcp->sock = -1;
+ freeaddrinfo(addr);
return -1;
}
+ freeaddrinfo(addr);
return tcp->sock;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment