static void fetch_broadcast_info(uint16_t port) { broadcast_count = 0; IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(pAdapterInfo)); unsigned long ulOutBufLen = sizeof(pAdapterInfo); if (pAdapterInfo == NULL) { return; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = malloc(ulOutBufLen); if (pAdapterInfo == NULL) { return; } } int ret; if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { IP_ADAPTER_INFO *pAdapter = pAdapterInfo; while (pAdapter) { IP gateway = {0}, subnet_mask = {0}; if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask) && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) { if (gateway.family == AF_INET && subnet_mask.family == AF_INET) { IP_Port *ip_port = &broadcast_ip_port[broadcast_count]; ip_port->ip.family = AF_INET; uint32_t gateway_ip = ntohl(gateway.ip4.uint32), subnet_ip = ntohl(subnet_mask.ip4.uint32); uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; ip_port->ip.ip4.uint32 = htonl(broadcast_ip); ip_port->port = port; broadcast_count++; if (broadcast_count >= MAX_INTERFACES) { return; } } } pAdapter = pAdapter->Next; } } if (pAdapterInfo) { free(pAdapterInfo); } }
/* Like tox_bootstrap_from_address but for TCP relays only. * * return 0 on failure. * return 1 on success. */ int tox_add_tcp_relay(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key) { Messenger *m = tox; IP_Port ip_port, ip_port_v4; if (!addr_parse_ip(address, &ip_port.ip)) { if (m->options.udp_disabled) /* Disable DNS when udp is disabled. */ return 0; IP *ip_extra = NULL; ip_init(&ip_port.ip, m->options.ipv6enabled); if (m->options.ipv6enabled) { /* setup for getting BOTH: an IPv6 AND an IPv4 address */ ip_port.ip.family = AF_UNSPEC; ip_reset(&ip_port_v4.ip); ip_extra = &ip_port_v4.ip; } if (!addr_resolve(address, &ip_port.ip, ip_extra)) return 0; } ip_port.port = htons(port); add_tcp_relay(m->net_crypto, ip_port, public_key); onion_add_path_node(m->onion_c, ip_port, public_key); //TODO: move this return 1; }
/* * addr_resolve_or_parse_ip * resolves string into an IP address * * address: a hostname (or something parseable to an IP address) * to: to.family MUST be initialized, either set to a specific IP version * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both * IP versions are acceptable * extra can be NULL and is only set in special circumstances, see returns * * returns in *tro a matching address (IPv6 or IPv4) * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC * returns 1 on success * returns 0 on failure */ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra) { if (!addr_resolve(address, to, extra)) if (!addr_parse_ip(address, to)) return 0; return 1; };
static void fetch_broadcast_info(uint16_t port) { IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO)); unsigned long ulOutBufLen = sizeof(IP_ADAPTER_INFO); if (pAdapterInfo == nullptr) { return; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { free(pAdapterInfo); pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); if (pAdapterInfo == nullptr) { return; } } /* We copy these to the static variables broadcast_* only at the end of fetch_broadcast_info(). * The intention is to ensure that even if multiple threads enter fetch_broadcast_info() concurrently, only valid * interfaces will be set to be broadcast to. * */ int count = 0; IP_Port ip_ports[MAX_INTERFACES]; int ret; if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { IP_ADAPTER_INFO *pAdapter = pAdapterInfo; while (pAdapter) { IP gateway = {0}, subnet_mask = {0}; if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask) && addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) { if (gateway.family == TOX_AF_INET && subnet_mask.family == TOX_AF_INET) { IP_Port *ip_port = &ip_ports[count]; ip_port->ip.family = TOX_AF_INET; uint32_t gateway_ip = net_ntohl(gateway.ip.v4.uint32), subnet_ip = net_ntohl(subnet_mask.ip.v4.uint32); uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1; ip_port->ip.ip.v4.uint32 = net_htonl(broadcast_ip); ip_port->port = port; count++; if (count >= MAX_INTERFACES) { break; } } } pAdapter = pAdapter->Next; } } if (pAdapterInfo) { free(pAdapterInfo); } broadcast_count = count; for (uint32_t i = 0; i < count; i++) { broadcast_ip_ports[i] = ip_ports[i]; } }