diff --git a/src/local_transport/local_transport.c b/src/local_transport/local_transport.c index 2d47f755..eda323ac 100644 --- a/src/local_transport/local_transport.c +++ b/src/local_transport/local_transport.c @@ -25,7 +25,7 @@ enum packet_drop { struct local_socket { struct local_socket* next; struct local_transport* owner; - struct local_interface interface; + struct local_interface iface; socket_t fd; void* handle; int present; @@ -122,7 +122,7 @@ static int same_address(const struct sockaddr_storage* a, const struct sockaddr_ static struct local_socket* find_socket(struct local_transport* t, const struct sockaddr_storage* source, uint32_t index) { for (struct local_socket* s = t->sockets; s; s = s->next) - if (s->interface.index == index && index && local_on_interface(&s->interface, source)) return s; + if (s->iface.index == index && index && local_on_interface(&s->iface, source)) return s; return NULL; } @@ -139,11 +139,11 @@ static int send_packet(struct local_socket* s, const struct sockaddr_storage* ad ssize_t result = socket_sendto(s->fd, data, LOCAL_HEADER_SIZE + len, (const struct sockaddr*)address, address_len); if (result != (ssize_t)(LOCAL_HEADER_SIZE + len)) { DEBUG_WARN(DEBUG_CATEGORY_DISCOVERY, "send failed type=%u interface=%u destination=%s bytes=%zu result=%zd error=%s", - type, s->interface.index, sockaddr_storage_to_str(address).str, len, result, socket_strerror(socket_get_error())); + type, s->iface.index, sockaddr_storage_to_str(address).str, len, result, socket_strerror(socket_get_error())); return -1; } DEBUG_DEBUG(DEBUG_CATEGORY_DISCOVERY, "sent type=%u interface=%u destination=%s peer=%016llx request=%llu bytes=%zu", - type, s->interface.index, sockaddr_storage_to_str(address).str, (unsigned long long)peer, (unsigned long long)request, len); + type, s->iface.index, sockaddr_storage_to_str(address).str, (unsigned long long)peer, (unsigned long long)request, len); return 0; } @@ -154,7 +154,7 @@ static void announce(struct local_socket* s, const struct sockaddr_storage* addr static void announce_all(struct local_transport* t) { if (!t->active || !t->broadcasts) return; for (struct local_socket* s = t->sockets; s; s = s->next) - if (s->interface.index) announce(s, &s->interface.broadcast); + if (s->iface.index) announce(s, &s->iface.broadcast); } static void delivery(struct local_transport* t, struct pending_entry* p, int status) { @@ -210,7 +210,7 @@ static void receive_packet(struct local_socket* s, struct sockaddr_storage* sour uint64_t now = get_time_tb(); struct peer_entry* p = find_peer(t, peer_id); DEBUG_DEBUG(DEBUG_CATEGORY_DISCOVERY, "received type=%u peer=%016llx interface=%u source=%s request=%llu bytes=%zu", - type, (unsigned long long)peer_id, s->interface.index, sockaddr_storage_to_str(source).str, (unsigned long long)request, len); + type, (unsigned long long)peer_id, s->iface.index, sockaddr_storage_to_str(source).str, (unsigned long long)request, len); if (type == LOCAL_ANNOUNCE) { if (destination || destination_epoch || request || !local_name_valid(payload, len)) { drop_packet(t, DROP_ANNOUNCE); return; @@ -228,7 +228,7 @@ static void receive_packet(struct local_socket* s, struct sockaddr_storage* sour } size_t j; for (j = 0; j < p->count; j++) - if (p->endpoints[j].index == s->interface.index && same_address(&p->endpoints[j].address, source)) break; + if (p->endpoints[j].index == s->iface.index && same_address(&p->endpoints[j].address, source)) break; int new_endpoint = j == p->count; if (new_endpoint) { if (j == ENDPOINT_MAX) { @@ -236,7 +236,7 @@ static void receive_packet(struct local_socket* s, struct sockaddr_storage* sour } p->count++; } - p->endpoints[j] = (struct local_endpoint){ .address = *source, .index = s->interface.index, .seen = now }; + p->endpoints[j] = (struct local_endpoint){ .address = *source, .index = s->iface.index, .seen = now }; if (changed) { DEBUG_DEBUG(DEBUG_CATEGORY_DISCOVERY, "device discovered/updated peer=%016llx name=%s endpoints=%zu", (unsigned long long)peer_id, p->peer.name, p->count); peers_changed(t); @@ -250,7 +250,7 @@ static void receive_packet(struct local_socket* s, struct sockaddr_storage* sour } size_t j; for (j = 0; j < p->count; j++) - if (p->endpoints[j].index == s->interface.index && same_address(&p->endpoints[j].address, source) && + if (p->endpoints[j].index == s->iface.index && same_address(&p->endpoints[j].address, source) && now - p->endpoints[j].seen < EXPIRE_TB) break; if (j == p->count) { drop_packet(t, DROP_ENDPOINT); return; } if (type == LOCAL_ACK) { @@ -313,14 +313,14 @@ static void socket_read(socket_t fd, void* arg) { if (size == -2) { drop_packet(t, DROP_HEADER); continue; } /* Unicast-сокет уже привязан к адресу интерфейса. При обмене двух процессов на одном * хосте ОС может указать loopback как ingress, но IPv6 scope нужен от локальной привязки. */ - if (socket->interface.index) index = socket->interface.index; + if (socket->iface.index) index = socket->iface.index; struct local_socket* s = find_socket(t, &source, index); if (!s) { drop_packet(t, DROP_NONLOCAL); continue; } if (source.ss_family == AF_INET6) ((struct sockaddr_in6*)&source)->sin6_scope_id = index; - receive_packet(s, &source, data, (size_t)size, !socket->interface.index); + receive_packet(s, &source, data, (size_t)size, !socket->iface.index); } } @@ -329,34 +329,34 @@ static void close_socket(struct local_socket* s) { socket_close_wrapper(s->fd); u_free(s); } -static struct local_socket* open_socket(struct local_transport* t, const struct local_interface* interface) { - int family = interface->address.ss_family, enabled = 1; +static struct local_socket* open_socket(struct local_transport* t, const struct local_interface* iface) { + int family = iface->address.ss_family, enabled = 1; struct local_socket* s = u_calloc(1, sizeof(*s)); if (!s) { DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "socket record allocation failed"); return NULL; } - s->owner = t; s->interface = *interface; s->present = 1; s->fd = socket_create_udp(family); + s->owner = t; s->iface = *iface; s->present = 1; s->fd = socket_create_udp(family); if (s->fd == SOCKET_INVALID) goto error; /* Общий порт используется только broadcast/multicast-приёмниками; unicast уходит на уникальные ephemeral-порты. */ - if ((!interface->index && socket_set_reuseaddr(s->fd, 1)) || socket_set_nonblocking(s->fd) || + if ((!iface->index && socket_set_reuseaddr(s->fd, 1)) || socket_set_nonblocking(s->fd) || local_receive_options(s->fd, family)) goto error; if (family == AF_INET && setsockopt(s->fd, SOL_SOCKET, SO_BROADCAST, (const char*)&enabled, sizeof(enabled))) goto error; - if (family == AF_INET && interface->index) { + if (family == AF_INET && iface->index) { int ttl = 1; if (setsockopt(s->fd, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl))) goto error; #ifdef IP_UNICAST_IF /* bind(IP) фиксирует источник, но не egress при перекрывающихся подсетях/VPN. */ - uint32_t index = htonl(interface->index); + uint32_t index = htonl(iface->index); if (setsockopt(s->fd, IPPROTO_IP, IP_UNICAST_IF, (const char*)&index, sizeof(index))) goto error; #endif } if (family == AF_INET6) { int hops = 1; if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&enabled, sizeof(enabled))) goto error; - if (interface->index && (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, - (const char*)&interface->index, sizeof(interface->index)) || + if (iface->index && (setsockopt(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (const char*)&iface->index, sizeof(iface->index)) || setsockopt(s->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&hops, sizeof(hops)))) goto error; } - struct sockaddr_storage address = interface->address; - if (!interface->index) { + struct sockaddr_storage address = iface->address; + if (!iface->index) { if (family == AF_INET) ((struct sockaddr_in*)&address)->sin_port = htons(LOCAL_TRANSPORT_PORT); else ((struct sockaddr_in6*)&address)->sin6_port = htons(LOCAL_TRANSPORT_PORT); } @@ -366,11 +366,11 @@ static struct local_socket* open_socket(struct local_transport* t, const struct if (!s->handle) goto error; s->next = t->sockets; t->sockets = s; DEBUG_INFO(DEBUG_CATEGORY_DISCOVERY, "local UDP socket opened family=%d interface=%u address=%s port=%u", - family, interface->index, sockaddr_storage_to_str(&address).str, socket_get_bound_port(s->fd)); + family, iface->index, sockaddr_storage_to_str(&address).str, socket_get_bound_port(s->fd)); return s; error: DEBUG_ERROR(DEBUG_CATEGORY_DISCOVERY, "local UDP socket failed family=%d interface=%u: %s", - family, interface->index, socket_strerror(socket_get_error())); + family, iface->index, socket_strerror(socket_get_error())); if (s->fd != SOCKET_INVALID) socket_close_wrapper(s->fd); u_free(s); return NULL; } @@ -394,9 +394,9 @@ static void reconcile(struct local_transport* t) { struct local_socket* receiver6 = NULL; int receiver4_found = 0; for (struct local_socket* s = t->sockets; s; s = s->next) { - s->present = !s->interface.index; - if (!s->interface.index && s->interface.address.ss_family == AF_INET6) receiver6 = s; - if (!s->interface.index && s->interface.address.ss_family == AF_INET) receiver4_found = 1; + s->present = !s->iface.index; + if (!s->iface.index && s->iface.address.ss_family == AF_INET6) receiver6 = s; + if (!s->iface.index && s->iface.address.ss_family == AF_INET) receiver4_found = 1; } if (!receiver4_found) { struct local_interface listener = {0}; listener.address.ss_family = AF_INET; @@ -410,9 +410,9 @@ static void reconcile(struct local_transport* t) { for (int i = 0; i < count; i++) { struct local_socket* found = NULL; for (struct local_socket* s = t->sockets; s; s = s->next) - if (s->interface.index == interfaces[i].index && same_address(&s->interface.address, &interfaces[i].address)) { found = s; break; } + if (s->iface.index == interfaces[i].index && same_address(&s->iface.address, &interfaces[i].address)) { found = s; break; } if (found) { - found->present = 1; found->interface = interfaces[i]; + found->present = 1; found->iface = interfaces[i]; continue; } open_socket(t, &interfaces[i]); @@ -422,22 +422,22 @@ static void reconcile(struct local_transport* t) { struct local_socket* s = *link; if (s->present) { link = &s->next; continue; } DEBUG_INFO(DEBUG_CATEGORY_DISCOVERY, "local UDP socket removed interface=%u address=%s", - s->interface.index, sockaddr_storage_to_str(&s->interface.address).str); + s->iface.index, sockaddr_storage_to_str(&s->iface.address).str); *link = s->next; close_socket(s); } if (!receiver6) return; for (size_t i = 0; i < t->joined6_count;) { int present = 0; for (struct local_socket* s = t->sockets; s; s = s->next) - if (s->interface.index == t->joined6[i] && s->interface.address.ss_family == AF_INET6) present = 1; + if (s->iface.index == t->joined6[i] && s->iface.address.ss_family == AF_INET6) present = 1; if (present) { i++; continue; } membership(receiver6, t->joined6[i], 0); t->joined6[i] = t->joined6[--t->joined6_count]; } for (struct local_socket* s = t->sockets; s; s = s->next) { - if (!s->interface.index || s->interface.address.ss_family != AF_INET6) continue; + if (!s->iface.index || s->iface.address.ss_family != AF_INET6) continue; size_t i; - for (i = 0; i < t->joined6_count; i++) if (t->joined6[i] == s->interface.index) break; - if (i == t->joined6_count && !membership(receiver6, s->interface.index, 1)) t->joined6[t->joined6_count++] = s->interface.index; + for (i = 0; i < t->joined6_count; i++) if (t->joined6[i] == s->iface.index) break; + if (i == t->joined6_count && !membership(receiver6, s->iface.index, 1)) t->joined6[t->joined6_count++] = s->iface.index; } } diff --git a/src/local_transport/platform.c b/src/local_transport/platform.c index 3272c963..220296bb 100644 --- a/src/local_transport/platform.c +++ b/src/local_transport/platform.c @@ -168,11 +168,11 @@ ssize_t local_receive(socket_t fd, void* data, size_t capacity, struct sockaddr_ #endif } -int local_on_interface(const struct local_interface* interface, const struct sockaddr_storage* source) { - if (source->ss_family != interface->address.ss_family || !ss_get_port(source)) return 0; +int local_on_interface(const struct local_interface* iface, const struct sockaddr_storage* source) { + if (source->ss_family != iface->address.ss_family || !ss_get_port(source)) return 0; if (source->ss_family == AF_INET6) return IN6_IS_ADDR_LINKLOCAL(&((const struct sockaddr_in6*)source)->sin6_addr); uint32_t address = ((const struct sockaddr_in*)source)->sin_addr.s_addr; - uint32_t own = ((const struct sockaddr_in*)&interface->address)->sin_addr.s_addr; - return address && address != UINT32_MAX && (address & interface->mask4) == (own & interface->mask4) && - address != (own | ~interface->mask4) && address != (own & interface->mask4); + uint32_t own = ((const struct sockaddr_in*)&iface->address)->sin_addr.s_addr; + return address && address != UINT32_MAX && (address & iface->mask4) == (own & iface->mask4) && + address != (own | ~iface->mask4) && address != (own & iface->mask4); } diff --git a/src/local_transport/platform.h b/src/local_transport/platform.h index 7e9aa52b..28fc73e4 100644 --- a/src/local_transport/platform.h +++ b/src/local_transport/platform.h @@ -22,6 +22,6 @@ int local_receive_options(socket_t fd, int family); /* -2 = пакет усечён, -1 = ошибка ОС. index — входящий интерфейс (в том числе для IPv4 broadcast). */ ssize_t local_receive(socket_t fd, void* data, size_t capacity, struct sockaddr_storage* source, uint32_t* index); /* Проверить адрес/порт источника: IPv4 той же подсети либо IPv6 link-local; 1 = подходит. */ -int local_on_interface(const struct local_interface* interface, const struct sockaddr_storage* source); +int local_on_interface(const struct local_interface* iface, const struct sockaddr_storage* source); #endif