From 5c53b6217a27b96eaf4a8699c7b32855de332643 Mon Sep 17 00:00:00 2001 From: sepfy Date: Mon, 22 Jul 2024 09:31:40 +0800 Subject: [PATCH] Add mdns and refactor socket --- src/address.c | 88 ++++++------ src/address.h | 24 ++-- src/agent.c | 45 ++++--- src/agent.h | 2 +- src/dtls_srtp.c | 2 +- src/dtls_srtp.h | 1 - src/ice.c | 76 +++-------- src/mdns.c | 179 +++++++++++++++++++++++++ src/mdns.h | 9 ++ src/peer_connection.c | 2 +- src/ports.c | 64 +++------ src/ports.h | 2 - src/socket.c | 303 ++++++++++++++++++++++++++++++++++++++++++ src/socket.h | 36 +++++ src/ssl_transport.c | 11 +- src/ssl_transport.h | 2 +- src/stun.c | 38 +++--- src/tcp.c | 168 ----------------------- src/tcp.h | 29 ---- src/udp.c | 268 ------------------------------------- src/udp.h | 35 ----- 21 files changed, 667 insertions(+), 717 deletions(-) create mode 100644 src/mdns.c create mode 100644 src/mdns.h create mode 100644 src/socket.c create mode 100644 src/socket.h delete mode 100644 src/tcp.c delete mode 100644 src/tcp.h delete mode 100644 src/udp.c delete mode 100644 src/udp.h diff --git a/src/address.c b/src/address.c index f63a727..541538c 100644 --- a/src/address.c +++ b/src/address.c @@ -6,70 +6,60 @@ #include #include +#include "utils.h" #include "address.h" -int addr_ipv4_validate(const char *ipv4, size_t len, Address *addr) { - - int start = 0; - int index = 0; - for (int i = 0; i < len; i++) { - - if (ipv4[i] != '.' && (ipv4[i] < '0' || ipv4[i] > '9')) { - return 0; - } else if (ipv4[i] == '.') { - - addr->ipv4[index++] = atoi(ipv4 + start); - start = i + 1; - } else if (i == (len - 1)) { - - addr->ipv4[index++] = atoi(ipv4 + start); - } else if (index == 4) { - return 0; - } +void addr_set_family(Address *addr, int family) { + switch (family) { + case AF_INET6: + addr->family = AF_INET6; + break; + case AF_INET: + default: + addr->family = AF_INET; + break; } - addr->family = AF_INET; - return 1; } -int addr_ipv6_validate(const char *ipv6, size_t len, Address *addr) { - int ret; - struct sockaddr_in6 sa6; - char astring[INET6_ADDRSTRLEN]; - ret = inet_pton(AF_INET6, ipv6, &(sa6.sin6_addr)); - inet_ntop(AF_INET6, &(sa6.sin6_addr), astring, INET6_ADDRSTRLEN); - memcpy(addr->ipv6, sa6.sin6_addr.s6_addr, 16); - return ret; +void addr_set_port(Address *addr, uint16_t port) { + addr->port = port; + switch (addr->family) { + case AF_INET6: + addr->sin6.sin6_port = htons(port); + break; + case AF_INET: + default: + addr->sin.sin_port = htons(port); + break; + } } -int addr_to_text(const Address *addr, char *buf, size_t len) { - switch (addr->family) { - case AF_INET: - return inet_ntop(AF_INET, addr->ipv4, buf, len) != NULL; - break; - case AF_INET6: - return inet_ntop(AF_INET6, addr->ipv6, buf, len) != NULL; - break; +int addr_from_string(const char *buf, Address *addr) { + if (inet_pton(AF_INET, buf, &(addr->sin.sin_addr)) == 1) { + addr_set_family(addr, AF_INET); + return 1; + } else if (inet_pton(AF_INET6, buf, &(addr->sin6.sin6_addr)) == 1) { + addr_set_family(addr, AF_INET6); + return 1; } return 0; } -int addr_equal(const Address *a, const Address *b) { - if (a->family != b->family) { - return 0; - } +int addr_to_string(const Address *addr, char *buf, size_t len) { - switch (a->family) { - case AF_INET: - for (int i = 0; i < 4; i++) { - if (a->ipv4[i] != b->ipv4[i]) { - return 0; - } - } - break; + memset(buf, 0, sizeof(len)); + switch (addr->family) { case AF_INET6: - break; + return inet_ntop(AF_INET6, &addr->sin6.sin6_addr, buf, len) != NULL; + case AF_INET: + default: + return inet_ntop(AF_INET, &addr->sin.sin_addr, buf, len) != NULL; } + return 0; +} +int addr_equal(const Address *a, const Address *b) { + // TODO return 1; } diff --git a/src/address.h b/src/address.h index 52e2eb1..a036144 100644 --- a/src/address.h +++ b/src/address.h @@ -1,24 +1,30 @@ #ifndef ADDRESS_H_ #define ADDRESS_H_ +#include +#include #include -typedef struct Address Address; - -struct Address { +#define ADDRSTRLEN INET6_ADDRSTRLEN +typedef struct Address { uint8_t family; + struct sockaddr_in sin; + struct sockaddr_in6 sin6; uint16_t port; - uint8_t ipv4[4]; - uint16_t ipv6[8]; +} Address; + +void addr_set_family(Address *addr, int family); + +void addr_set_port(Address *addr, uint16_t port); -}; +int addr_inet6_validate(const char *ipv6, size_t len, Address *addr); -int addr_ipv6_validate(const char *ipv6, size_t len, Address *addr); +int addr_inet_validate(const char *ipv4, size_t len, Address *addr); -int addr_ipv4_validate(const char *ipv4, size_t len, Address *addr); +int addr_to_string(const Address *addr, char *buf, size_t len); -int addr_to_text(const Address *addr, char *buf, size_t len); +int addr_from_string(const char *str, Address *addr); int addr_equal(const Address *a, const Address *b); diff --git a/src/agent.c b/src/agent.c index bad0dc7..7ac6281 100644 --- a/src/agent.c +++ b/src/agent.c @@ -6,7 +6,7 @@ #include #include -#include "udp.h" +#include "socket.h" #include "utils.h" #include "stun.h" #include "ice.h" @@ -21,14 +21,14 @@ static int agent_create_sockets(Agent *agent) { int ret; - if ((ret = udp_socket_create(&agent->udp_sockets[0], AF_INET)) < 0) { + if ((ret = udp_socket_open(&agent->udp_sockets[0], AF_INET, 0)) < 0) { LOGE("Failed to create UDP socket."); return ret; } LOGI("create IPv4 UDP socket: %d", agent->udp_sockets[0].fd); #if CONFIG_IPV6 - if ((ret = udp_socket_create(&agent->udp_sockets[1], AF_INET6)) < 0) { + if ((ret = udp_socket_open(&agent->udp_sockets[1], AF_INET6, 0)) < 0) { LOGE("Failed to create IPv6 UDP socket."); return ret; } @@ -92,7 +92,7 @@ static int agent_create_host_addr(Agent *agent) { udp_socket = &agent->udp_sockets[0]; if (ports_get_host_addr(&udp_socket->bind_addr)) { - LOGD("addr: %d.%d.%d.%d", udp_socket->bind_addr.ipv4[0], udp_socket->bind_addr.ipv4[1], udp_socket->bind_addr.ipv4[2], udp_socket->bind_addr.ipv4[3]); + //LOGD("addr: %d.%d.%d.%d", udp_socket->bind_addr.ipv4[0], udp_socket->bind_addr.ipv4[1], udp_socket->bind_addr.ipv4[2], udp_socket->bind_addr.ipv4[3]); IceCandidate *ice_candidate = agent->local_candidates + agent->local_candidates_count++; ice_candidate_create(ice_candidate, agent->local_candidates_count, ICE_CANDIDATE_TYPE_HOST, &udp_socket->bind_addr); } @@ -100,7 +100,7 @@ static int agent_create_host_addr(Agent *agent) { #if CONFIG_IPV6 udp_socket = &agent->udp_sockets[1]; if (ports_get_host_addr(&udp_socket->bind_addr)) { - LOGD("addr: %x:%x:%x:%x:%x:%x:%x:%x", udp_socket->bind_addr.ipv6[0], udp_socket->bind_addr.ipv6[1], udp_socket->bind_addr.ipv6[2], udp_socket->bind_addr.ipv6[3], udp_socket->bind_addr.ipv6[4], udp_socket->bind_addr.ipv6[5], udp_socket->bind_addr.ipv6[6], udp_socket->bind_addr.ipv6[7]); + //LOGD("addr: %x:%x:%x:%x:%x:%x:%x:%x", udp_socket->bind_addr.ipv6[0], udp_socket->bind_addr.ipv6[1], udp_socket->bind_addr.ipv6[2], udp_socket->bind_addr.ipv6[3], udp_socket->bind_addr.ipv6[4], udp_socket->bind_addr.ipv6[5], udp_socket->bind_addr.ipv6[6], udp_socket->bind_addr.ipv6[7]); IceCandidate *ice_candidate = agent->local_candidates + agent->local_candidates_count++; ice_candidate_create(ice_candidate, agent->local_candidates_count, ICE_CANDIDATE_TYPE_HOST, &udp_socket->bind_addr); } @@ -234,8 +234,10 @@ void agent_deinit(Agent *agent) { */ void agent_gather_candidate(Agent *agent, const char *urls, const char *username, const char *credential) { - char *port = NULL; + char *pos; + int port; char hostname[64]; + char addr_string[ADDRSTRLEN]; int i; int addr_type[1] = {AF_INET}; // ipv6 no need stun Address resolved_addr; @@ -247,24 +249,27 @@ void agent_gather_candidate(Agent *agent, const char *urls, const char *username do { - if ((port = strstr(urls + 5, ":")) == NULL) { + if ((pos = strstr(urls + 5, ":")) == NULL) { break; } - resolved_addr.port = atoi(port + 1); - if (resolved_addr.port <= 0) { + port = atoi(pos + 1); + if (port <= 0) { break; + LOGE("Cannot parse port"); } - LOGI("resolved_addr.port: %d", resolved_addr.port); - snprintf(hostname, port - urls - 5 + 1, "%s", urls + 5); + snprintf(hostname, pos - urls - 5 + 1, "%s", urls + 5); for (i = 0; i < sizeof(addr_type) / sizeof(addr_type[0]); i++) { - resolved_addr.family = addr_type[i]; - if (ports_resolve_addr(hostname, &resolved_addr) == 0) { - LOGI("resolved_addr.ipv4: %d.%d.%d.%d", - resolved_addr.ipv4[0], resolved_addr.ipv4[1], resolved_addr.ipv4[2], resolved_addr.ipv4[3]); + + if (ports_resolve_addr(hostname, &resolved_addr) != 0) { + continue; } + + addr_set_port(&resolved_addr, port); + addr_to_string(&resolved_addr, addr_string, sizeof(addr_string)); + LOGI("stun/turn server %s:%d", addr_string, port); if (strncmp(urls, "stun:", 5) == 0) { LOGD("create stun addr"); @@ -453,6 +458,7 @@ a=candidate:1 1 UDP 1 36.231.28.50 38143 typ srflx int agent_connectivity_check(Agent *agent) { + char addr_string[ADDRSTRLEN]; uint8_t buf[1400]; StunMessage msg; @@ -465,13 +471,8 @@ int agent_connectivity_check(Agent *agent) { if (agent->nominated_pair->conncheck % AGENT_CONNCHECK_PERIOD == 0) { - if (agent->nominated_pair->remote->addr.family == AF_INET) { - LOGD("send binding request to remote ip: %d.%d.%d.%d, port: %d", agent->nominated_pair->remote->addr.ipv4[0], agent->nominated_pair->remote->addr.ipv4[1], agent->nominated_pair->remote->addr.ipv4[2], agent->nominated_pair->remote->addr.ipv4[3], agent->nominated_pair->remote->addr.port); - } else { - char astring[INET6_ADDRSTRLEN]; - addr_to_text(&(agent->nominated_pair->remote->addr), astring, INET6_ADDRSTRLEN); - LOGD("send binding request to remote ip: %s, port: %d", astring, agent->nominated_pair->remote->addr.port); - } + addr_to_string(&agent->nominated_pair->remote->addr, addr_string, sizeof(addr_string)); + LOGD("send binding request to remote ip: %s, port: %d", addr_string, agent->nominated_pair->remote->addr.port); agent_create_binding_request(agent, &msg); agent_socket_send(agent, &agent->nominated_pair->remote->addr, msg.buf, msg.size); } diff --git a/src/agent.h b/src/agent.h index 58567fc..fe1b9e9 100644 --- a/src/agent.h +++ b/src/agent.h @@ -10,7 +10,7 @@ #include -#include "udp.h" +#include "socket.h" #include "utils.h" #include "stun.h" #include "ice.h" diff --git a/src/dtls_srtp.c b/src/dtls_srtp.c index ca60d51..79e412f 100644 --- a/src/dtls_srtp.c +++ b/src/dtls_srtp.c @@ -7,7 +7,7 @@ #include "mbedtls/ssl.h" #include "dtls_srtp.h" #include "address.h" -#include "udp.h" +#include "socket.h" #include "config.h" #include "utils.h" diff --git a/src/dtls_srtp.h b/src/dtls_srtp.h index e6acfbd..c9322a6 100644 --- a/src/dtls_srtp.h +++ b/src/dtls_srtp.h @@ -15,7 +15,6 @@ #include -#include "udp.h" #include "address.h" #define SRTP_MASTER_KEY_LENGTH 16 diff --git a/src/ice.c b/src/ice.c index 15771e5..e11ba2d 100644 --- a/src/ice.c +++ b/src/ice.c @@ -7,8 +7,9 @@ #include #include +#include "mdns.h" #include "ports.h" -#include "udp.h" +#include "socket.h" #include "utils.h" #include "ice.h" @@ -52,59 +53,34 @@ void ice_candidate_create(IceCandidate *candidate, int foundation, IceCandidateT void ice_candidate_to_description(IceCandidate *candidate, char *description, int length) { - char typ_raddr[64]; + char addr_string[ADDRSTRLEN]; + char typ_raddr[128]; memset(typ_raddr, 0, sizeof(typ_raddr)); + addr_to_string(&candidate->raddr, addr_string, sizeof(addr_string)); switch (candidate->type) { - case ICE_CANDIDATE_TYPE_HOST: snprintf(typ_raddr, sizeof(typ_raddr), "host"); break; - case ICE_CANDIDATE_TYPE_SRFLX: - snprintf(typ_raddr, sizeof(typ_raddr), "srflx raddr %d.%d.%d.%d rport %d", - candidate->raddr.ipv4[0], - candidate->raddr.ipv4[1], - candidate->raddr.ipv4[2], - candidate->raddr.ipv4[3], - candidate->raddr.port); + snprintf(typ_raddr, sizeof(typ_raddr), "srflx raddr %s rport %d", addr_string, candidate->raddr.port); break; case ICE_CANDIDATE_TYPE_RELAY: - snprintf(typ_raddr, sizeof(typ_raddr), "relay raddr %d.%d.%d.%d rport %d", - candidate->raddr.ipv4[0], - candidate->raddr.ipv4[1], - candidate->raddr.ipv4[2], - candidate->raddr.ipv4[3], - candidate->raddr.port); + snprintf(typ_raddr, sizeof(typ_raddr), "relay raddr %s rport %d", addr_string, candidate->raddr.port); default: break; } - LOGI("candidate->addr.family: %d", candidate->addr.family); - if (candidate->addr.family == AF_INET6) { - char ipv6str[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, candidate->addr.ipv6, ipv6str, INET6_ADDRSTRLEN); - snprintf(description, length, "a=candidate:%d %d %s %" PRIu32 " %s %d typ %s\n", - candidate->foundation, - candidate->component, - candidate->transport, - candidate->priority, - ipv6str, - candidate->addr.port, - typ_raddr); - } else { - snprintf(description, length, "a=candidate:%d %d %s %" PRIu32 " %d.%d.%d.%d %d typ %s\n", - candidate->foundation, - candidate->component, - candidate->transport, - candidate->priority, - candidate->addr.ipv4[0], - candidate->addr.ipv4[1], - candidate->addr.ipv4[2], - candidate->addr.ipv4[3], - candidate->addr.port, - typ_raddr); - } + + addr_to_string(&candidate->addr, addr_string, sizeof(addr_string)); + snprintf(description, length, "a=candidate:%d %d %s %" PRIu32 " %s %d typ %s\n", + candidate->foundation, + candidate->component, + candidate->transport, + candidate->priority, + addr_string, + candidate->addr.port, + typ_raddr); } int ice_candidate_from_description(IceCandidate *candidate, char *description, char *end) { @@ -120,7 +96,6 @@ int ice_candidate_from_description(IceCandidate *candidate, char *description, c memset(buf, 0, sizeof(buf)); strncpy(buf, split_start, split_end - split_start); switch (index) { - case 0: candidate->foundation = atoi(buf); break; @@ -139,22 +114,15 @@ int ice_candidate_from_description(IceCandidate *candidate, char *description, c break; case 4: if (strstr(buf, "local") != 0) { - if (ports_resolve_mdns_host(buf, &candidate->addr) < 0) { + if (mdns_resolve_addr(buf, &candidate->addr) == 0) { return -1; } - candidate->addr.family = AF_INET; - LOGD("mDNS host: %s, ip: %d.%d.%d.%d", buf, candidate->addr.ipv4[0], candidate->addr.ipv4[1], candidate->addr.ipv4[2], candidate->addr.ipv4[3]); - } else if (addr_ipv4_validate(buf, strlen(buf), &candidate->addr)) { - candidate->addr.family = AF_INET; - } else if (addr_ipv6_validate(buf, strlen(buf), &candidate->addr)) { - candidate->addr.family = AF_INET6; - } else { - return -1; - } - + } else if (addr_from_string(buf, &candidate->addr) == 0) { + return -1; + } break; case 5: - candidate->addr.port = atoi(buf); + addr_set_port(&candidate->addr, atoi(buf)); break; case 7: diff --git a/src/mdns.c b/src/mdns.c new file mode 100644 index 0000000..0592244 --- /dev/null +++ b/src/mdns.c @@ -0,0 +1,179 @@ +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" +#include "address.h" +#include "socket.h" + +#define MDNS_GROUP "224.0.0.251" +#define MDNS_PORT 5353 + +typedef struct DnsHeader { + uint16_t id; + uint16_t flags; + uint16_t qestions; + uint16_t answer_rrs; + uint16_t authority_rrs; + uint16_t additional_rrs; +} DnsHeader; + +typedef struct DnsAnswer { + uint16_t type; + uint16_t class; + uint32_t ttl; + uint16_t length; + uint8_t data[0]; +} DnsAnswer; + +typedef struct DnsQuery { + uint16_t type; + uint16_t class; +} DnsQuery; + +static int mdns_parse_answer(uint8_t *buf, int size, Address *addr) { + + char *pos; + int flags_qr; + DnsHeader *header; + DnsAnswer *answer; + + if (size < sizeof(DnsHeader)) { + LOGE("response too short"); + return -1; + } + + header = (DnsHeader *)buf; + flags_qr = ntohs(header->flags) >> 15; + if (flags_qr != 1) { + LOGD("flag is not a DNS response"); + return -1; + } + + buf += sizeof(DnsHeader); + pos = strstr((char*)buf, "local"); + LOGI("\nbuf=>%s\n", buf); + if (pos == NULL) { + LOGI("not a mDNS response"); + return -1; + } + + + pos += 6; + answer = (DnsAnswer *)pos; + LOGI("lenght: %d\n", answer->length); + uint8_t *debug = (uint8_t*)&answer->ttl; + printf("%.2x %.2x %.2x %.2x\n", debug[0], debug[1], debug[2], debug[3]); + printf("type: %d, class: %d, ttl: %lu, length: %d\n", ntohs(answer->type), ntohs(answer->class), ntohl(answer->ttl), ntohs(answer->length)); + if (ntohs(answer->length) != 4) { + LOGI("invalid length"); + return -1; + } + + memcpy(&addr->sin.sin_addr, answer->data, 4); + return 0; +} + +static int mdns_build_query(const char *hostname, uint8_t *buf, int size) { + + int total_size, len, offset; + const char *label, *dot; + DnsHeader *dns_header; + DnsQuery *dns_query; + + total_size = sizeof(dns_header) + strlen(hostname) + sizeof(dns_query) + 2; + if (size < total_size) { + printf("buf size is not enough"); + return -1; + } + + memset(buf, 0, size); + dns_header = (DnsHeader*)buf; + dns_header->qestions = 0x0100; + offset = sizeof(DnsHeader); + + // Append hostname to query + label = hostname; + while (*label) { + dot = strchr(label, '.'); + if (!dot) { + dot = label + strlen(label); + } + len = dot - label; + buf[offset++] = len; + memcpy(buf + offset, label, len); + offset += len; + label = *dot ? dot + 1 : dot; + } + + buf[offset++] = 0x00; + + dns_query = (DnsQuery*) (buf + offset); + dns_query->type = 0x0100; + dns_query->class = 0x0100; + return total_size; +} + +int mdns_resolve_addr(const char *hostname, Address *addr) { + + Address mcast_addr; + UdpSocket udp_socket; + uint8_t buf[256]; + char addr_string[ADDRSTRLEN]; + int send_retry = 3; + int recv_retry = 5; + int ret = -1; + int resolved = 0; + int size; + struct timeval tv; + int maxfd = 0; + fd_set rfds; + tv.tv_sec = 1; + tv.tv_usec = 0; + + memset(&mcast_addr, 0, sizeof(mcast_addr)); + addr_from_string(MDNS_GROUP, &mcast_addr); + addr_set_port(&mcast_addr, MDNS_PORT); + + if (udp_socket_open(&udp_socket, AF_INET, MDNS_PORT) < 0) { + LOGE("Failed to create socket"); + return -1; + } + + FD_ZERO(&rfds); + maxfd = udp_socket.fd; + + while (!resolved && send_retry--) { + LOGI("sendto"); + size = mdns_build_query(hostname, buf, sizeof(buf)); + udp_socket_sendto(&udp_socket, &mcast_addr, buf, size); + recv_retry = 5; + while (!resolved && recv_retry--) { + LOGI("select %d", recv_retry); + FD_SET(udp_socket.fd, &rfds); + ret = select(maxfd + 1, &rfds, NULL, NULL, &tv); + if (ret < 0) { + LOGE("select error"); + } else if (ret == 0) { + // timeout + } else { + if (FD_ISSET(udp_socket.fd, &rfds)) { + ret = udp_socket_recvfrom(&udp_socket, &mcast_addr, buf, sizeof(buf)); + if (!mdns_parse_answer(buf, ret, addr)) { + addr_to_string(addr, addr_string, sizeof(addr_string)); + addr_set_family(addr, AF_INET); + resolved = 1; + break; + } + } + } + } + } + LOGI("Resolve:%d", resolved); + udp_socket_close(&udp_socket); + return resolved; +} + diff --git a/src/mdns.h b/src/mdns.h new file mode 100644 index 0000000..a2c73a1 --- /dev/null +++ b/src/mdns.h @@ -0,0 +1,9 @@ +#ifndef MDNS_H_ +#define MDNS_H_ + +#include +#include "address.h" + +int mdns_resolve_addr(const char *hostname, Address *addr); + +#endif // MDNS_H_ diff --git a/src/peer_connection.c b/src/peer_connection.c index 097d84f..cd09578 100644 --- a/src/peer_connection.c +++ b/src/peer_connection.c @@ -278,7 +278,7 @@ static void peer_connection_state_new(PeerConnection *pc) { for (int i = 0; i < sizeof(pc->config.ice_servers)/sizeof(pc->config.ice_servers[0]); ++i) { if (pc->config.ice_servers[i].urls) { - LOGI("ice_servers: %s\n", pc->config.ice_servers[i].urls); + LOGI("ice_servers: %s", pc->config.ice_servers[i].urls); agent_gather_candidate(&pc->agent, pc->config.ice_servers[i].urls, pc->config.ice_servers[i].username, pc->config.ice_servers[i].credential); } } diff --git a/src/ports.c b/src/ports.c index 777f23e..e32384f 100644 --- a/src/ports.c +++ b/src/ports.c @@ -30,17 +30,17 @@ int ports_get_host_addr(Address *addr) { switch (addr->family) { case AF_INET6: if (esp_netif_get_ip6_global(netif, &ip6_info) == ESP_OK) { - memcpy(addr->ipv6, &ip6_info.addr, 16); + memcpy(&addr->sin6.sin6_addr, &ip6_info.addr, 16); ret = 1; } else if (esp_netif_get_ip6_linklocal(netif, &ip6_info) == ESP_OK) { - memcpy(addr->ipv6, &ip6_info.addr, 16); + memcpy(&addr->sin6.sin6_addr, &ip6_info.addr, 16); ret = 1; } break; case AF_INET: default: if (esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) { - memcpy(addr->ipv4, &ip_info.ip.addr, 4); + memcpy(&addr->sin.sin_addr, &ip_info.ip.addr, 4); ret = 1; } break; @@ -59,11 +59,11 @@ int ports_get_host_addr(Address *addr) { if (ifa->ifa_addr->sa_family == addr->family) { switch (ifa->ifa_addr->sa_family) { case AF_INET: - memcpy(addr->ipv4, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr, 4); + memcpy(&addr->sin, ifa->ifa_addr, sizeof(struct sockaddr_in)); ret = 1; break; case AF_INET6: - memcpy(addr->ipv6, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr.s6_addr, 16); + memcpy(&addr->sin6, ifa->ifa_addr, sizeof(struct sockaddr_in6)); ret = 1; break; default: @@ -130,76 +130,46 @@ LOGI("get_host_address inside while loop"); } int ports_resolve_addr(const char *host, Address *addr) { + + char addr_string[ADDRSTRLEN]; int ret = -1; struct addrinfo hints, *res, *p; - int family; int status; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(host, NULL, &hints, &res)) != 0) { - //LOGE("getaddrinfo error: %s\n", gai_strerror(status)); - LOGE("getaddrinfo %s error: %d\n", host, status); + LOGE("getaddrinfo error: %d\n", status); return ret; } - if (addr->family == AF_INET6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - for (p = res; p != NULL; p = p->ai_next) { - if (p->ai_family == family) { - switch (p->ai_family) { + // TODO: Support for IPv6 + addr_set_family(addr, AF_INET); + for (p = res; p != NULL; p = p->ai_next) { + if (p->ai_family == addr->family) { + switch (addr->family) { case AF_INET6: - memcpy(addr->ipv6, &((struct sockaddr_in6 *)p->ai_addr)->sin6_addr.s6_addr, 16); + memcpy(&addr->sin6, p->ai_addr, sizeof(struct sockaddr_in6)); break; case AF_INET: - LOGI("AF_INET"); - memcpy(addr->ipv4, &((struct sockaddr_in *)p->ai_addr)->sin_addr.s_addr, 4); default: + memcpy(&addr->sin, p->ai_addr, sizeof(struct sockaddr_in)); break; } ret = 0; } } + addr_to_string(addr, addr_string, sizeof(addr_string)); + LOGI("Resolved %s -> %s", host, addr_string); freeaddrinfo(res); return ret; } -int ports_resolve_mdns_host(const char *host, Address *addr) { -#ifdef ESP32 - int ret = -1; - struct esp_ip4_addr esp_addr; - char host_name[64] = {0}; - char *pos = strstr(host, ".local"); - snprintf(host_name, pos - host + 1, "%s", host); - esp_addr.addr = 0; - - esp_err_t err = mdns_query_a(host_name, 2000, &esp_addr); - if (err) { - if (err == ESP_ERR_NOT_FOUND) { - LOGW("%s: Host was not found!", esp_err_to_name(err)); - return ret; - } - LOGE("Query Failed: %s", esp_err_to_name(err)); - return ret; - } - - memcpy(addr->ipv4, &esp_addr.addr, 4); - return ret; -#else - return ports_resolve_addr(host, addr); -#endif -} - uint32_t ports_get_epoch_time() { struct timeval tv; gettimeofday(&tv, NULL); return (uint32_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; } - diff --git a/src/ports.h b/src/ports.h index 460f08c..d5b4eee 100644 --- a/src/ports.h +++ b/src/ports.h @@ -3,7 +3,6 @@ #include #include "address.h" -#include "udp.h" int ports_resolve_addr(const char *host, Address *addr); @@ -14,4 +13,3 @@ int ports_get_host_addr(Address *addr); uint32_t ports_get_epoch_time(); #endif // PORTS_H_ - diff --git a/src/socket.c b/src/socket.c new file mode 100644 index 0000000..796478a --- /dev/null +++ b/src/socket.c @@ -0,0 +1,303 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "socket.h" + +int udp_socket_open(UdpSocket *udp_socket, int family, int port) { + + int ret; + int reuse = 1; + struct sockaddr *sa; + socklen_t sock_len; + + udp_socket->bind_addr.family = family; + switch (family) { + case AF_INET6: + udp_socket->fd = socket(AF_INET6, SOCK_DGRAM, 0); + udp_socket->bind_addr.sin6.sin6_family = AF_INET6; + udp_socket->bind_addr.sin6.sin6_port = htons(port); + udp_socket->bind_addr.sin6.sin6_addr = in6addr_any; + udp_socket->bind_addr.port = ntohs(udp_socket->bind_addr.sin6.sin6_port); + sa = (struct sockaddr *)&udp_socket->bind_addr.sin6; + sock_len = sizeof(struct sockaddr_in6); + break; + case AF_INET: + default: + udp_socket->fd = socket(AF_INET, SOCK_DGRAM, 0); + udp_socket->bind_addr.sin.sin_family = AF_INET; + udp_socket->bind_addr.sin.sin_port = htons(port); + udp_socket->bind_addr.sin.sin_addr.s_addr = htonl(INADDR_ANY); + sa = (struct sockaddr *)&udp_socket->bind_addr.sin; + sock_len = sizeof(struct sockaddr_in); + break; + } + + if (udp_socket->fd < 0) { + LOGE("Failed to create socket"); + return -1; + } + + do { + if ((ret = setsockopt(udp_socket->fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) < 0) { + LOGE("reuse failed"); + break; + } + + if ((ret = bind(udp_socket->fd, sa, sock_len)) < 0) { + LOGE("Failed to bind socket: %d", ret); + break; + } + + if (getsockname(udp_socket->fd, sa, &sock_len) < 0) { + LOGE("Get socket info failed"); + break; + } + } while (0); + + if (ret < 0) { + udp_socket_close(udp_socket); + return -1; + } + + switch (udp_socket->bind_addr.family) { + case AF_INET6: + udp_socket->bind_addr.port = ntohs(udp_socket->bind_addr.sin6.sin6_port); + break; + case AF_INET: + default: + udp_socket->bind_addr.port = ntohs(udp_socket->bind_addr.sin.sin_port); + break; + } + + return 0; +} + +void udp_socket_close(UdpSocket *udp_socket) { + + if (udp_socket->fd > 0) { + close(udp_socket->fd); + } +} + +int udp_socket_sendto(UdpSocket *udp_socket, Address *addr, const uint8_t *buf, int len) { + + struct sockaddr *sa; + socklen_t sock_len; + int ret = -1; + + if (udp_socket->fd < 0) { + LOGE("sendto before socket init"); + return -1; + } + + switch (addr->family) { + case AF_INET6: + sa = (struct sockaddr *)&addr->sin6; + sock_len = sizeof(struct sockaddr_in6); + break; + case AF_INET: + default: + sa = (struct sockaddr *)&addr->sin; + sock_len = sizeof(struct sockaddr_in); + break; + } + + if ((ret = sendto(udp_socket->fd, buf, len, 0, sa, sock_len)) < 0) { + LOGE("Failed to sendto: %s", strerror(errno)); + return -1; + } + + return ret; +} + +int udp_socket_recvfrom(UdpSocket *udp_socket, Address *addr, uint8_t *buf, int len) { + + struct sockaddr_in6 sin6; + struct sockaddr_in sin; + struct sockaddr *sa; + socklen_t sock_len; + int ret; + + if (udp_socket->fd < 0) { + LOGE("recvfrom before socket init"); + return -1; + } + + switch (udp_socket->bind_addr.family) { + case AF_INET6: + sa = (struct sockaddr *)&sin6; + sock_len = sizeof(struct sockaddr_in6); + break; + case AF_INET: + default: + sa = (struct sockaddr *)&sin; + sock_len = sizeof(struct sockaddr_in); + break; + } + + if ((ret = recvfrom(udp_socket->fd, buf, len, 0, sa, &sock_len)) < 0) { + LOGE("Failed to recvfrom: %s", strerror(errno)); + return -1; + } + + if (addr) { + switch (udp_socket->bind_addr.family) { + case AF_INET6: + addr->family = AF_INET6; + addr->port = htons(addr->sin6.sin6_port); + memcpy(&addr->sin6, &sin6, sizeof(struct sockaddr_in6)); + break; + case AF_INET: + default: + addr->family = AF_INET; + addr->port = htons(addr->sin.sin_port); + memcpy(&addr->sin, &sin, sizeof(struct sockaddr_in)); + break; + } + } + + return ret; +} + +int tcp_socket_open(TcpSocket *tcp_socket, int family) { + + tcp_socket->bind_addr.family = family; + switch (family) { + case AF_INET6: + tcp_socket->fd = socket(AF_INET6, SOCK_STREAM, 0); + break; + case AF_INET: + default: + tcp_socket->fd = socket(AF_INET, SOCK_STREAM, 0); + break; + } + + if (tcp_socket->fd < 0) { + LOGE("Failed to create socket"); + return -1; + } + return 0; +} + +int tcp_socket_connect(TcpSocket *tcp_socket, Address *addr) { + + char addr_string[ADDRSTRLEN]; + int ret; + struct sockaddr *sa; + socklen_t sock_len; + + if (tcp_socket->fd < 0) { + LOGE("Connect before socket init"); + return -1; + } + + switch (addr->family) { + case AF_INET6: + sa = (struct sockaddr *)&addr->sin6; + sock_len = sizeof(struct sockaddr_in6); + break; + case AF_INET: + default: + sa = (struct sockaddr *)&addr->sin; + sock_len = sizeof(struct sockaddr_in); + break; + } + + addr_to_string(addr, addr_string, sizeof(addr_string)); + LOGI("Connecting to server: %s:%d", addr_string, addr->port); + if ((ret = connect(tcp_socket->fd, sa, sock_len)) < 0) { + LOGE("Failed to connect to server"); + return -1; + } + + LOGI("Server is connected"); + return 0; +} + +void tcp_socket_close(TcpSocket *tcp_socket) { + + if (tcp_socket->fd > 0) { + close(tcp_socket->fd); + } +} + +int tcp_socket_send(TcpSocket *tcp_socket, const uint8_t *buf, int len) { + + fd_set write_set; + struct timeval tv; + int ret = -1; + + if (tcp_socket->fd < 0) { + + LOGE("sendto before socket init"); + return -1; + } + + FD_ZERO(&write_set); + FD_SET(tcp_socket->fd, &write_set); + + tv.tv_sec = 0; + tv.tv_usec = 500000; + + if ((ret = select(tcp_socket->fd + 1, NULL, &write_set, NULL, &tv)) < 0) { + + LOGE("Failed to select: %s", strerror(errno)); + return -1; + } + + if (FD_ISSET(tcp_socket->fd, &write_set)) { + + ret = send(tcp_socket->fd, buf, len, 0); + if (ret < 0) { + LOGE("Failed to send: %s", strerror(errno)); + return -1; + } + } + + return ret; +} + +int tcp_socket_recv(TcpSocket *tcp_socket, uint8_t *buf, int len) { + + fd_set read_set; + struct timeval tv; + int ret; + + if (tcp_socket->fd < 0) { + + LOGE("recvfrom before socket init"); + return -1; + } + + FD_ZERO(&read_set); + FD_SET(tcp_socket->fd, &read_set); + tv.tv_sec = 0; + tv.tv_usec = 500000; + + if ((ret = select(tcp_socket->fd + 1, &read_set, NULL, NULL, &tv)) < 0) { + + LOGE("Failed to select: %s", strerror(errno)); + return -1; + } + + if (FD_ISSET(tcp_socket->fd, &read_set)) { + + ret = recv(tcp_socket->fd, buf, len, 0); + if (ret < 0) { + LOGE("Failed to recv: %s", strerror(errno)); + return -1; + } + } + + return ret; +} diff --git a/src/socket.h b/src/socket.h new file mode 100644 index 0000000..378170a --- /dev/null +++ b/src/socket.h @@ -0,0 +1,36 @@ +#ifndef SOCKET_H_ +#define SOCKET_H_ + +#include "address.h" + +typedef struct UdpSocket { + int fd; + Address bind_addr; +} UdpSocket; + +typedef struct TcpSocket { + int fd; + Address bind_addr; +} TcpSocket; + +int udp_socket_open(UdpSocket *udp_socket, int family, int port); + +int udp_socket_bind(UdpSocket *udp_socket, int port); + +void udp_socket_close(UdpSocket *udp_socket); + +int udp_socket_sendto(UdpSocket *udp_socket, Address *bind_addr, const uint8_t *buf, int len); + +int udp_socket_recvfrom(UdpSocket *udp_sock, Address *bind_addr, uint8_t *buf, int len); + +int tcp_socket_open(TcpSocket *tcp_socket, int family); + +int tcp_socket_connect(TcpSocket *tcp_socket, Address *addr); + +void tcp_socket_close(TcpSocket *tcp_socket); + +int tcp_socket_send(TcpSocket *tcp_socket, const uint8_t *buf, int len); + +int tcp_socket_recv(TcpSocket *tcp_socket, uint8_t *buf, int len); + +#endif // SOCKET_H_ diff --git a/src/ssl_transport.c b/src/ssl_transport.c index fb58e7b..150f0ca 100644 --- a/src/ssl_transport.c +++ b/src/ssl_transport.c @@ -73,14 +73,9 @@ int ssl_transport_connect(NetworkContext_t *net_ctx, return -1; } - tcp_socket_open(&net_ctx->tcp_socket); - tcp_blocking_timeout(&net_ctx->tcp_socket, 1000); - if (ports_resolve_addr(host, &resolved_addr) < 0) { - LOGE("Failed to connect tcp server"); - return -1; - } - - resolved_addr.port = port; + tcp_socket_open(&net_ctx->tcp_socket, AF_INET); + ports_resolve_addr(host, &resolved_addr); + addr_set_port(&resolved_addr, port); tcp_socket_connect(&net_ctx->tcp_socket, &resolved_addr); mbedtls_ssl_set_bio(&net_ctx->ssl, &net_ctx->tcp_socket, diff --git a/src/ssl_transport.h b/src/ssl_transport.h index 1180517..fd1cbe5 100644 --- a/src/ssl_transport.h +++ b/src/ssl_transport.h @@ -6,7 +6,7 @@ #include #include -#include "tcp.h" +#include "socket.h" #include "transport_interface.h" struct NetworkContext { diff --git a/src/stun.c b/src/stun.c index 80e6794..aaa9421 100644 --- a/src/stun.c +++ b/src/stun.c @@ -63,18 +63,14 @@ void stun_msg_create(StunMessage *msg, uint16_t type) { void stun_set_mapped_address(char *value, uint8_t *mask, Address *addr) { - int i; - uint8_t *family = (uint8_t *)(value + 1); uint16_t *port = (uint16_t *)(value + 2); uint8_t *ipv4 = (uint8_t *)(value + 4); *family = 0x01; *port = htons(addr->port); - - for (i = 0; i < 4; i++) { - ipv4[i] = addr->ipv4[i]; - } + + memcpy(ipv4, &addr->sin.sin_addr, 4); //LOGD("XOR Mapped Address Family: 0x%02x", *family); //LOGD("XOR Mapped Address Port: %d", *port); @@ -84,26 +80,26 @@ void stun_set_mapped_address(char *value, uint8_t *mask, Address *addr) { void stun_get_mapped_address(char *value, uint8_t *mask, Address *addr) { int i; - uint32_t *addr32 = (uint32_t *)addr->ipv4; - uint16_t *addr16 = (uint16_t *)addr->ipv6; - addr->family = value[1]; - addr->port = ntohs(*(uint16_t *)(value + 2) ^ *(uint16_t*)mask); - LOGD("family: %d, %d", AF_INET, AF_INET6); - LOGD("XOR Mapped Address Family: 0x%02x", addr->family); - LOGD("XOR Mapped Address Port: %d", addr->port); - if (addr->family == 0x02) { - addr->family = AF_INET6; + char addr_string[ADDRSTRLEN]; + uint32_t *addr32 = (uint32_t *)&addr->sin.sin_addr; + uint16_t *addr16 = (uint16_t *)&addr->sin6.sin6_addr; + uint8_t family = value[1]; + if (family == 0x02) { + addr_set_family(addr, AF_INET6); for (i = 0; i < 8; i++) { addr16[i] = (*(uint16_t *)(value + 4 + 2*i) ^ *(uint16_t*)(mask + 2*i)); } - LOGD("XOR Mapped Address Address: %x:%x:%x:%x:%x:%x:%x:%x", addr->ipv6[0], addr->ipv6[1], addr->ipv6[2], addr->ipv6[3], addr->ipv6[4], addr->ipv6[5], addr->ipv6[6], addr->ipv6[7]); - - } else if (addr->family == 0x01) { - addr->family = AF_INET; - *addr32 = (*(uint32_t *)(value + 4) ^ *(uint32_t*)mask); - LOGD("XOR Mapped Address Address: %d.%d.%d.%d", addr->ipv4[0], addr->ipv4[1], addr->ipv4[2], addr->ipv4[3]); + } else if (family == 0x01) { + addr_set_family(addr, AF_INET); + *addr32 = (*(uint32_t *)(value + 4) ^ *(uint32_t*)mask); } + addr_to_string(addr, addr_string, sizeof(addr_string)); + addr_set_port(addr, ntohs(*(uint16_t *)(value + 2) ^ *(uint16_t*)mask)); + + LOGD("XOR Mapped Address Family: 0x%02x", addr->family); + LOGD("XOR Mapped Address Port: %d", addr->port); + LOGD("XOR Mapped Address Address: %s", addr_string); } void stun_parse_msg_buf(StunMessage *msg) { diff --git a/src/tcp.c b/src/tcp.c deleted file mode 100644 index 825aa84..0000000 --- a/src/tcp.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "tcp.h" - -void tcp_blocking_timeout(TcpSocket *tcp_socket, long long int ms) { - - tcp_socket->timeout_sec = ms/1000; - tcp_socket->timeout_usec = ms%1000*1000; -} - -int tcp_socket_open(TcpSocket *tcp_socket) { - - tcp_socket->fd = socket(AF_INET, SOCK_STREAM, 0); - - if (tcp_socket->fd < 0) { - - LOGE("Failed to create socket"); - return -1; - } - - tcp_blocking_timeout(tcp_socket, 5); - return 0; -} - -int tcp_socket_connect(TcpSocket *tcp_socket, Address *addr) { - - if (tcp_socket->fd < 0) { - LOGE("Failed to create socket"); - return -1; - } - - struct sockaddr_in sin; - socklen_t sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_port = htons(addr->port); - memcpy(&sin.sin_addr.s_addr, addr->ipv4, 4); - LOGI("port: %d", addr->port); - LOGI("addr: %s", inet_ntoa(sin.sin_addr)); - if (connect(tcp_socket->fd, (struct sockaddr *)&sin, sin_len) < 0) { - - LOGE("Failed to connect to server"); - return -1; - } - LOGI("Connected to server"); - return 0; -} - -void tcp_socket_close(TcpSocket *tcp_socket) { - - if (tcp_socket->fd > 0) { - close(tcp_socket->fd); - } -} - -int tcp_get_local_address(TcpSocket *tcp_socket, Address *addr) { - - struct sockaddr_in sin; - - socklen_t len = sizeof(sin); - - if (tcp_socket->fd < 0) { - LOGE("Failed to create socket"); - return -1; - } - - if (getsockname(tcp_socket->fd, (struct sockaddr *)&sin, &len) < 0) { - LOGE("Failed to get local address"); - return -1; - } - - memcpy(addr->ipv4, &sin.sin_addr.s_addr, 4); - - addr->port = ntohs(sin.sin_port); - - addr->family = AF_INET; - - LOGD("local port: %d", addr->port); - LOGD("local address: %d.%d.%d.%d", addr->ipv4[0], addr->ipv4[1], addr->ipv4[2], addr->ipv4[3]); - - return 0; -} - -int tcp_socket_send(TcpSocket *tcp_socket, const uint8_t *buf, int len) { - - fd_set write_set; - struct timeval tv; - int ret = -1; - - if (tcp_socket->fd < 0) { - - LOGE("sendto before socket init"); - return -1; - } - - FD_ZERO(&write_set); - FD_SET(tcp_socket->fd, &write_set); - - tv.tv_sec = tcp_socket->timeout_sec; - tv.tv_usec = tcp_socket->timeout_usec; - - if ((ret = select(tcp_socket->fd + 1, NULL, &write_set, NULL, &tv)) < 0) { - - LOGE("Failed to select: %s", strerror(errno)); - return -1; - } - - if (FD_ISSET(tcp_socket->fd, &write_set)) { - - ret = send(tcp_socket->fd, buf, len, 0); - - if (ret < 0) { - - LOGE("Failed to send: %s", strerror(errno)); - return -1; - } - } - - return ret; -} - -int tcp_socket_recv(TcpSocket *tcp_socket, uint8_t *buf, int len) { - - fd_set read_set; - struct timeval tv; - int ret; - - if (tcp_socket->fd < 0) { - - LOGE("recvfrom before socket init"); - return -1; - } - - FD_ZERO(&read_set); - FD_SET(tcp_socket->fd, &read_set); - tv.tv_sec = tcp_socket->timeout_sec; - tv.tv_usec = tcp_socket->timeout_usec; - - if ((ret = select(tcp_socket->fd + 1, &read_set, NULL, NULL, &tv)) < 0) { - - LOGE("Failed to select: %s", strerror(errno)); - return -1; - } - - if (FD_ISSET(tcp_socket->fd, &read_set)) { - - ret = recv(tcp_socket->fd, buf, len, 0); - - if (ret < 0) { - - LOGE("Failed to recv: %s", strerror(errno)); - return -1; - } - } - - return ret; -} - diff --git a/src/tcp.h b/src/tcp.h deleted file mode 100644 index 3c80534..0000000 --- a/src/tcp.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef TCP_SOCKET_H_ -#define TCP_SOCKET_H_ - -#include "address.h" - -typedef struct TcpSocket TcpSocket; - -struct TcpSocket { - - int fd; - Address bind_addr; - long long int timeout_sec; - long int timeout_usec; -}; - -int tcp_socket_open(TcpSocket *tcp_socket); - -int tcp_socket_connect(TcpSocket *tcp_socket, Address *addr); - -void tcp_socket_close(TcpSocket *tcp_socket); - -int tcp_socket_send(TcpSocket *tcp_socket, const uint8_t *buf, int len); - -int tcp_socket_recv(TcpSocket *tcp_socket, uint8_t *buf, int len); - -void tcp_blocking_timeout(TcpSocket *tcp_socket, long long int ms); - -#endif // TCP_SOCKET_H_ - diff --git a/src/udp.c b/src/udp.c deleted file mode 100644 index 9801c2d..0000000 --- a/src/udp.c +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include "utils.h" -#include "udp.h" - -void udp_blocking_timeout(UdpSocket *udp_socket, long long int ms) { - - udp_socket->timeout_sec = ms/1000; - udp_socket->timeout_usec = ms%1000*1000; -} - -int udp_socket_create(UdpSocket *udp_socket, int family) { - - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr *sa; - socklen_t sin_len; - - switch (family) { - case AF_INET6: - udp_socket->fd = socket(AF_INET6, SOCK_DGRAM, 0); - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(0); - sin6.sin6_addr = in6addr_any; - sa = (struct sockaddr *)&sin6; - sin_len = sizeof(sin6); - break; - case AF_INET: - default: - udp_socket->fd = socket(AF_INET, SOCK_DGRAM, 0); - sin.sin_family = AF_INET; - sin.sin_port = htons(0); - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sa = (struct sockaddr *)&sin; - sin_len = sizeof(sin); - break; - } - - if (udp_socket->fd < 0) { - - LOGE("Failed to create socket"); - return -1; - } - - if (bind(udp_socket->fd, sa, sin_len) < 0) { - - LOGE("Failed to bind socket"); - return -1; - } - - if (getsockname(udp_socket->fd, (struct sockaddr *)&sin, &sin_len) < 0) { - LOGE("Failed to get local address"); - return -1; - } - - LOGI("local port: %d", ntohs(sin.sin_port)); - udp_socket->bind_addr.family = sin.sin_family; - udp_socket->bind_addr.port = ntohs(sin.sin_port); - return 0; -} - -int udp_socket_open(UdpSocket *udp_socket, int family) { - - switch (family) { - case AF_INET6: - udp_socket->fd = socket(AF_INET6, SOCK_DGRAM, 0); - break; - case AF_INET: - default: - udp_socket->fd = socket(AF_INET, SOCK_DGRAM, 0); - break; - } - - if (udp_socket->fd < 0) { - - LOGE("Failed to create socket"); - return -1; - } - - //int flags = fcntl(udp_socket->fd, F_GETFL, 0); - //fcntl(udp_socket->fd, F_SETFL, flags | O_NONBLOCK); - udp_blocking_timeout(udp_socket, 5); - return 0; -} - -int udp_socket_bind(UdpSocket *udp_socket, Address *addr) { - - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr *sa; - socklen_t sin_len; - - if (udp_socket->fd < 0) { - LOGE("Failed to create socket"); - return -1; - } - - switch (addr->family) { - case AF_INET6: - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(addr->port); - sin6.sin6_addr = in6addr_any; - sa = (struct sockaddr *)&sin6; - sin_len = sizeof(sin6); - break; - case AF_INET: - default: - sin.sin_family = AF_INET; - sin.sin_port = htons(addr->port); - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sa = (struct sockaddr *)&sin; - sin_len = sizeof(sin); - break; - } - - if (bind(udp_socket->fd, sa, sin_len) < 0) { - - LOGE("Failed to bind socket"); - return -1; - } - - udp_socket->bind_addr.family = addr->family; - udp_socket->bind_addr.port = addr->port; - memcpy(udp_socket->bind_addr.ipv4, addr->ipv4, 4); - LOGD("bind_addr: %p", &udp_socket->bind_addr); - return 0; -} - -void udp_socket_close(UdpSocket *udp_socket) { - - if (udp_socket->fd > 0) { - close(udp_socket->fd); - } -} - -int udp_get_local_address(UdpSocket *udp_socket, Address *addr) { - - struct sockaddr_in sin; - - socklen_t len = sizeof(sin); - - if (udp_socket->fd < 0) { - LOGE("Failed to create socket"); - return -1; - } - - if (getsockname(udp_socket->fd, (struct sockaddr *)&sin, &len) < 0) { - LOGE("Failed to get local address"); - return -1; - } - - memcpy(addr->ipv4, &sin.sin_addr.s_addr, 4); - - addr->port = ntohs(sin.sin_port); - - addr->family = AF_INET; - - LOGD("local port: %d", addr->port); - LOGD("local address: %d.%d.%d.%d", addr->ipv4[0], addr->ipv4[1], addr->ipv4[2], addr->ipv4[3]); - - return 0; -} - -int udp_socket_sendto(UdpSocket *udp_socket, Address *addr, const uint8_t *buf, int len) { - - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr *sa; - socklen_t sin_len; - int ret = -1; - - if (udp_socket->fd < 0) { - - LOGE("sendto before socket init"); - return -1; - } - - switch (addr->family) { - case AF_INET6: - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(addr->port); - memcpy(&sin6.sin6_addr, addr->ipv6, 16); - sa = (struct sockaddr *)&sin6; - sin_len = sizeof(sin6); - break; - case AF_INET: - default: - sin.sin_family = AF_INET; - sin.sin_port = htons(addr->port); - memcpy(&sin.sin_addr.s_addr, addr->ipv4, 4); - sa = (struct sockaddr *)&sin; - sin_len = sizeof(sin); - break; - } - - ret = sendto(udp_socket->fd, buf, len, 0, sa, sin_len); - - if (ret < 0) { - - LOGE("Failed to sendto: %s", strerror(errno)); - return -1; - } - - return ret; -} - -int udp_socket_recvfrom(UdpSocket *udp_socket, Address *addr, uint8_t *buf, int len) { - - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - struct sockaddr *sa; - socklen_t sin_len; - int ret; - - if (udp_socket->fd < 0) { - - LOGE("recvfrom before socket init"); - return -1; - } - - switch (udp_socket->bind_addr.family) { - case AF_INET6: - sin_len = sizeof(sin6); - sa = (struct sockaddr *)&sin6; - break; - case AF_INET: - default: - sin_len = sizeof(sin); - sa = (struct sockaddr *)&sin; - break; - } - - ret = recvfrom(udp_socket->fd, buf, len, 0, sa, &sin_len); - if (ret < 0) { - LOGE("Failed to recvfrom: %s", strerror(errno)); - return -1; - } - - if (addr) { - switch (udp_socket->bind_addr.family) { - case AF_INET6: - addr->family = AF_INET6; - addr->port = ntohs(sin6.sin6_port); - memcpy(addr->ipv6, &sin6.sin6_addr, 16); - break; - case AF_INET: - default: - addr->family = AF_INET; - addr->port = ntohs(sin.sin_port); - memcpy(addr->ipv4, &sin.sin_addr.s_addr, 4); - break; - } - } - - return ret; -} - diff --git a/src/udp.h b/src/udp.h deleted file mode 100644 index 90fda81..0000000 --- a/src/udp.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef UDP_SOCKET_H_ -#define UDP_SOCKET_H_ - -#include "address.h" - -typedef struct UdpSocket UdpSocket; - -struct UdpSocket { - - int fd; - Address bind_addr; - long long int timeout_sec; - long int timeout_usec; -}; - -int udp_socket_create(UdpSocket *udp_socket, int family); - -int udp_socket_open(UdpSocket *udp_socket, int family); - -int udp_socket_bind(UdpSocket *udp_socket, Address *addr); - -void udp_socket_close(UdpSocket *udp_socket); - -int udp_socket_sendto(UdpSocket *udp_socket, Address *addr, const uint8_t *buf, int len); - -int udp_socket_recvfrom(UdpSocket *udp_socket, Address *addr, uint8_t *buf, int len); - -int udp_socket_get_host_address(UdpSocket *udp_socket, Address *addr); - -int udp_resolve_mdns_host(const char *host, Address *addr); - -void udp_blocking_timeout(UdpSocket *udp_socket, long long int ms); - -#endif // UDP_SOCKET_H_ -