static NMDevice * get_peer (NMDeviceVeth *self) { NMDeviceVethPrivate *priv = NM_DEVICE_VETH_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self), *peer = NULL; NMPlatformVethProperties props; if (priv->ever_had_peer) return priv->peer; if (!nm_platform_veth_get_properties (nm_device_get_ifindex (device), &props)) { _LOGW (LOGD_HW, "could not read veth properties"); return NULL; } peer = nm_manager_get_device_by_ifindex (nm_manager_get (), props.peer); if (peer && NM_IS_DEVICE_VETH (peer)) { set_peer (self, peer); set_peer (NM_DEVICE_VETH (peer), device); } return priv->peer; }
/* NOTE: this code must be fast, and not do any calculations */ static void turnc_handler(int err, uint16_t scode, const char *reason, const struct sa *relay_addr, const struct sa *mapped_addr, const struct stun_msg *msg, void *arg) { struct allocation *alloc = arg; struct allocator *allocator = alloc->allocator; struct timeval now; struct sa peer; if (err) { (void)re_fprintf(stderr, "[%u] turn error: %m\n", alloc->ix, err); alloc->err = err; goto term; } if (scode) { if (scode == 300 && is_connection_oriented(alloc) && alloc->redirc++ < REDIRC_MAX) { const struct stun_attr *alt; alt = stun_msg_attr(msg, STUN_ATTR_ALT_SERVER); if (!alt) goto term; re_printf("[%u] redirecting to new server %J\n", alloc->ix, &alt->v.alt_server); alloc->srv = alt->v.alt_server; alloc->turnc = mem_deref(alloc->turnc); alloc->tlsc = mem_deref(alloc->tlsc); alloc->tc = mem_deref(alloc->tc); alloc->dtls_sock = mem_deref(alloc->dtls_sock); alloc->us = mem_deref(alloc->us); err = start(alloc); if (err) goto term; return; } (void)re_fprintf(stderr, "[%u] turn error: %u %s\n", alloc->ix, scode, reason); alloc->err = EPROTO; goto term; } if (sa_af(relay_addr) != sa_af(mapped_addr)) { re_fprintf(stderr, "allocation: address-family mismatch" " (mapped=%J, relay=%J)\n", mapped_addr, relay_addr); err = EAFNOSUPPORT; goto term; } alloc->ok = true; alloc->relay = *relay_addr; (void)gettimeofday(&now, NULL); alloc->atime = (double)(now.tv_sec - alloc->sent.tv_sec) * 1000; alloc->atime += (double)(now.tv_usec - alloc->sent.tv_usec) / 1000; /* save information from the TURN server */ if (!allocator->server_info) { struct stun_attr *attr; allocator->server_auth = (NULL != stun_msg_attr(msg, STUN_ATTR_MSG_INTEGRITY)); attr = stun_msg_attr(msg, STUN_ATTR_SOFTWARE); if (attr) { str_ncpy(allocator->server_software, attr->v.software, sizeof(allocator->server_software)); } allocator->mapped_addr = *mapped_addr; allocator->server_info = true; attr = stun_msg_attr(msg, STUN_ATTR_LIFETIME); if (attr) { allocator->lifetime = attr->v.lifetime; } } peer = *mapped_addr; sa_set_port(&peer, sa_port(&alloc->laddr_tx)); err = set_peer(alloc, &peer); if (err) goto term; return; term: alloc->alloch(err, scode, reason, NULL, NULL, alloc->arg); }