Пример #1
0
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;
}
Пример #2
0
/* 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);
}