コード例 #1
0
static int test_open(void *ctx, UNUSED void const *master_ctx)
{
	fr_listen_test_t	*io_ctx = talloc_get_type_abort(ctx, fr_listen_test_t);

	io_ctx->sockfd = fr_socket_server_udp(&io_ctx->ipaddr, &io_ctx->port, NULL, true);
	if (io_ctx->sockfd < 0) {
		fr_perror("radius_test: Failed creating socket");
		exit(EXIT_FAILURE);
	}

	if (fr_socket_bind(io_ctx->sockfd, &io_ctx->ipaddr, &io_ctx->port, NULL) < 0) {
		fr_perror("radius_test: Failed binding to socket");
		exit(EXIT_FAILURE);
	}

	return 0;
}
コード例 #2
0
ファイル: dhcpclient.c プロジェクト: geaaru/freeradius-server
static int send_with_socket(RADIUS_PACKET **reply, RADIUS_PACKET *request)
{
	int on = 1;

#ifdef HAVE_LINUX_IF_PACKET_H
	if (raw_mode) {
		sockfd = fr_dhcpv4_raw_socket_open(&ll, iface_ind);
		if (sockfd < 0) {
			ERROR("Error opening socket");
			return -1;
		}
	} else
#endif
	{
		sockfd = fr_socket_server_udp(&request->src_ipaddr, &request->src_port, NULL, false);
		if (sockfd < 0) {
			ERROR("Error opening socket: %s", fr_strerror());
			return -1;
		}

		if (fr_socket_bind(sockfd, &request->src_ipaddr, &request->src_port, NULL) < 0) {
			ERROR("Error binding socket: %s", fr_strerror());
			return -1;
		}
	}


	/*
	 *	Set option 'receive timeout' on socket.
	 *	Note: in case of a timeout, the error will be "Resource temporarily unavailable".
	 */
	if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(struct timeval)) == -1) {
		ERROR("Failed setting socket timeout: %s", fr_syserror(errno));
		return -1;
	}

	if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
		ERROR("Can't set broadcast option: %s", fr_syserror(errno));
		return -1;
	}
	request->sockfd = sockfd;

#ifdef HAVE_LINUX_IF_PACKET_H
	if (raw_mode) {
		if (fr_dhcpv4_raw_packet_send(sockfd, &ll, request) < 0) {
			ERROR("Failed sending (fr_dhcpv4_raw_packet_send): %s", fr_syserror(errno));
			return -1;
		}
		if (!reply_expected) return 0;

		*reply = fr_dhcpv4_recv_raw_loop(sockfd, &ll, request);
		if (!*reply) {
			ERROR("Error receiving reply (fr_dhcpv4_recv_raw_loop)");
			return -1;
		}
	} else
#endif
	{
		if (fr_dhcpv4_udp_packet_send(request) < 0) {
			ERROR("Failed sending: %s", fr_syserror(errno));
			return -1;
		}
		if (!reply_expected) return 0;

		*reply = fr_dhcpv4_udp_packet_recv(sockfd);
		if (!*reply) {
			if (errno == EAGAIN) {
				fr_strerror(); /* clear error */
				ERROR("Timed out waiting for reply");
			} else {
				ERROR("Error receiving reply");
			}
			return -1;
		}
	}

	return 0;
}
コード例 #3
0
/** Open a UDP listener for DHCPV4
 *
 */
static int mod_open(fr_listen_t *li)
{
	proto_dhcpv4_udp_t const	*inst = talloc_get_type_abort_const(li->app_io_instance, proto_dhcpv4_udp_t);
	proto_dhcpv4_udp_thread_t	*thread = talloc_get_type_abort(li->thread_instance, proto_dhcpv4_udp_thread_t);

	int				sockfd, rcode;
	uint16_t			port = inst->port;
	CONF_SECTION			*server_cs;
	CONF_ITEM			*ci;

	li->fd = sockfd = fr_socket_server_udp(&inst->ipaddr, &port, inst->port_name, true);
	if (sockfd < 0) {
		PERROR("Failed opening UDP socket");
	error:
		return -1;
	}

	/*
	 *	Set SO_REUSEPORT before bind, so that all packets can
	 *	listen on the same destination IP address.
	 */
	if (1) {
		int on = 1;

		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) {
			ERROR("Failed to set socket 'reuseport': %s", fr_syserror(errno));
			close(sockfd);
			return -1;
		}
	}

	if (inst->broadcast) {
		int on = 1;

		if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
			ERROR("Failed to set broadcast option: %s", fr_syserror(errno));
			close(sockfd);
			return -1;
		}
	}

	/*
	 *	SUID up is really only needed if interface is set, OR port <1024.
	 */
	rad_suid_up();
	rcode = fr_socket_bind(sockfd, &inst->ipaddr, &port, inst->interface);
	rad_suid_down();
	if (rcode < 0) {
		close(sockfd);
		PERROR("Failed binding socket");
		goto error;
	}

	thread->sockfd = sockfd;

	ci = cf_parent(inst->cs); /* listen { ... } */
	rad_assert(ci != NULL);
	ci = cf_parent(ci);
	rad_assert(ci != NULL);

	server_cs = cf_item_to_section(ci);

	thread->name = fr_app_io_socket_name(thread, &proto_dhcpv4_udp,
					     NULL, 0,
					     &inst->ipaddr, inst->port,
					     inst->interface);

	DEBUG("Listening on dhcpv4 address %s bound to virtual server %s",
	      thread->name, cf_section_name2(server_cs));

	return 0;
}
コード例 #4
0
/** Open a UDP listener for RADIUS
 *
 */
static int mod_open(fr_listen_t *li)
{
	proto_radius_udp_t const       	*inst = talloc_get_type_abort_const(li->app_io_instance, proto_radius_udp_t);
	proto_radius_udp_thread_t	*thread = talloc_get_type_abort(li->thread_instance, proto_radius_udp_thread_t);

	int				sockfd;
	uint16_t			port = inst->port;
	CONF_SECTION			*server_cs;
	CONF_ITEM			*ci;

	li->fd = sockfd = fr_socket_server_udp(&inst->ipaddr, &port, inst->port_name, true);
	if (sockfd < 0) {
		PERROR("Failed opening UDP socket");
	error:
		return -1;
	}

	/*
	 *	Set SO_REUSEPORT before bind, so that all packets can
	 *	listen on the same destination IP address.
	 */
	if (1) {
		int on = 1;

		if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) {
			ERROR("Failed to set socket 'reuseport': %s", fr_syserror(errno));
			return -1;
		}
	}

#ifdef SO_RCVBUF
	if (inst->recv_buff_is_set) {
		int opt;

		opt = inst->recv_buff;
		if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(int)) < 0) {
			WARN("Failed setting 'recv_buf': %s", fr_syserror(errno));
		}
	}
#endif

#ifdef SO_SNDBUF
	if (inst->send_buff_is_set) {
		int opt;

		opt = inst->send_buff;
		if (setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(int)) < 0) {
			WARN("Failed setting 'send_buf': %s", fr_syserror(errno));
		}
	}
#endif

	if (fr_socket_bind(sockfd, &inst->ipaddr, &port, inst->interface) < 0) {
		close(sockfd);
		PERROR("Failed binding socket");
		goto error;
	}

	thread->sockfd = sockfd;

	ci = cf_parent(inst->cs); /* listen { ... } */
	rad_assert(ci != NULL);
	ci = cf_parent(ci);
	rad_assert(ci != NULL);

	server_cs = cf_item_to_section(ci);

	thread->name = fr_app_io_socket_name(thread, &proto_radius_udp,
					     NULL, 0,
					     &inst->ipaddr, inst->port,
					     inst->interface);

	// @todo - also print out auth / acct / coa, etc.
	DEBUG("Listening on radius address %s bound to virtual server %s",
	      thread->name, cf_section_name2(server_cs));

	return 0;
}