⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 detail.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				data->fp = NULL;				listener->fd = -1;				data->state = STATE_UNOPENED;				rad_assert(data->vps == NULL);				return 0;			}			/*			 *	Else go read something.			 */			break;			/*			 *	Read more value-pair's, unless we're			 *	at EOF.  In that case, queue whatever			 *	we have.			 */		case STATE_READING:			if (!feof(data->fp)) break;			data->state = STATE_QUEUED;			/* FALL-THROUGH */		case STATE_QUEUED:			goto alloc_packet;			/*			 *	We still have an outstanding packet.			 *	Don't read any more.			 */		case STATE_RUNNING:			return 0;			/*			 *	If there's no reply, keep			 *	retransmitting the current packet			 *	forever.			 */		case STATE_NO_REPLY:			data->state = STATE_QUEUED;			goto alloc_packet;							/*			 *	We have a reply.  Clean up the old			 *	request, and go read another one.			 */		case STATE_REPLIED:			pairfree(&data->vps);			data->state = STATE_HEADER;			goto do_header;	}		tail = &data->vps;	while (*tail) tail = &(*tail)->next;	/*	 *	Read a header, OR a value-pair.	 */	while (fgets(buffer, sizeof(buffer), data->fp)) {		/*		 *	Badly formatted file: delete it.		 *		 *	FIXME: Maybe flag an error?		 */		if (!strchr(buffer, '\n')) {			pairfree(&data->vps);			goto cleanup;		}		/*		 *	We're reading VP's, and got a blank line.		 *	Queue the packet.		 */		if ((data->state == STATE_READING) &&		    (buffer[0] == '\n')) {			data->state = STATE_QUEUED;			break;		}		/*		 *	Look for date/time header, and read VP's if		 *	found.  If not, keep reading lines until we		 *	find one.		 */		if (data->state == STATE_HEADER) {			int y;			if (sscanf(buffer, "%*s %*s %*d %*d:%*d:%*d %d", &y)) {				data->state = STATE_READING;			}			continue;		}		/*		 *	We have a full "attribute = value" line.		 *	If it doesn't look reasonable, skip it.		 *		 *	FIXME: print an error for badly formatted attributes?		 */		if (sscanf(buffer, "%255s = %1023s", key, value) != 2) {			continue;		}		/*		 *	Skip non-protocol attributes.		 */		if (!strcasecmp(key, "Request-Authenticator")) continue;		/*		 *	Set the original client IP address, based on		 *	what's in the detail file.		 *		 *	Hmm... we don't set the server IP address.		 *	or port.  Oh well.		 */		if (!strcasecmp(key, "Client-IP-Address")) {			data->client_ip.af = AF_INET;			ip_hton(value, AF_INET, &data->client_ip);			continue;		}		/*		 *	The original time at which we received the		 *	packet.  We need this to properly calculate		 *	Acct-Delay-Time.		 */		if (!strcasecmp(key, "Timestamp")) {			data->timestamp = atoi(value);			vp = paircreate(PW_PACKET_ORIGINAL_TIMESTAMP,					PW_TYPE_DATE);			if (vp) {				vp->vp_date = (uint32_t) data->timestamp;				*tail = vp;				tail = &(vp->next);			}			continue;		}		/*		 *	Read one VP.		 *		 *	FIXME: do we want to check for non-protocol		 *	attributes like radsqlrelay does?		 */		vp = NULL;		if ((userparse(buffer, &vp) > 0) &&		    (vp != NULL)) {			*tail = vp;			tail = &(vp->next);		}	}	/*	 *	Some kind of error.	 *	 *	FIXME: Leave the file in-place, and warn the	 *	administrator?	 */	if (ferror(data->fp)) goto cleanup;	/*	 *	Process the packet.	 */ alloc_packet:	rad_assert(data->state == STATE_QUEUED);	/*	 *	We're done reading the file, but we didn't read	 *	anything.  Clean up, and don't return anything.	 */	if (!data->vps) {		data->state = STATE_HEADER;		return 0;	}	/*	 *	Allocate the packet.  If we fail, it's a serious	 *	problem.	 */	packet = rad_alloc(1);	if (!packet) {		radlog(L_ERR, "FATAL: Failed allocating memory for detail");		exit(1);	}	memset(packet, 0, sizeof(*packet));	packet->sockfd = -1;	packet->src_ipaddr.af = AF_INET;	packet->src_ipaddr.ipaddr.ip4addr.s_addr = htonl(INADDR_NONE);	packet->code = PW_ACCOUNTING_REQUEST;	packet->timestamp = time(NULL);	/*	 *	Remember where it came from, so that we don't	 *	proxy it to the place it came from...	 */	if (data->client_ip.af != AF_UNSPEC) {		packet->src_ipaddr = data->client_ip;	}	vp = pairfind(packet->vps, PW_PACKET_SRC_IP_ADDRESS);	if (vp) {		packet->src_ipaddr.af = AF_INET;		packet->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;	} else {		vp = pairfind(packet->vps, PW_PACKET_SRC_IPV6_ADDRESS);		if (vp) {			packet->src_ipaddr.af = AF_INET6;			memcpy(&packet->src_ipaddr.ipaddr.ip6addr,			       &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));		}	}	vp = pairfind(packet->vps, PW_PACKET_DST_IP_ADDRESS);	if (vp) {		packet->dst_ipaddr.af = AF_INET;		packet->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;	} else {		vp = pairfind(packet->vps, PW_PACKET_DST_IPV6_ADDRESS);		if (vp) {			packet->dst_ipaddr.af = AF_INET6;			memcpy(&packet->dst_ipaddr.ipaddr.ip6addr,			       &vp->vp_ipv6addr, sizeof(vp->vp_ipv6addr));		}	}	/*	 *	We've got to give SOME value for Id & ports, so that	 *	the packets can be added to the request queue.	 *	However, we don't want to keep track of used/unused	 *	id's and ports, as that's a lot of work.  This hack	 *	ensures that (if we have real random numbers), that	 *	there will be a collision on every 2^(16+15+15+24 - 1)	 *	packets, on average.  That means we can read 2^37	 *	packets before having a collision, which means it's	 *	effectively impossible.	 */	packet->id = fr_rand() & 0xffff;	packet->src_port = 1024 + (fr_rand() & 0x7fff);	packet->dst_port = 1024 + (fr_rand() & 0x7fff);	packet->dst_ipaddr.af = AF_INET;	packet->dst_ipaddr.ipaddr.ip4addr.s_addr = htonl((INADDR_LOOPBACK & ~0xffffff) | (fr_rand() & 0xffffff));	/*	 *	If everything's OK, this is a waste of memory.	 *	Otherwise, it lets us re-send the original packet	 *	contents, unmolested.	 */	packet->vps = paircopy(data->vps);	/*	 *	Look for Acct-Delay-Time, and update	 *	based on Acct-Delay-Time += (time(NULL) - timestamp)	 */	vp = pairfind(packet->vps, PW_ACCT_DELAY_TIME);	if (!vp) {		vp = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);		rad_assert(vp != NULL);		pairadd(&packet->vps, vp);	}	if (data->timestamp != 0) {		vp->vp_integer += time(NULL) - data->timestamp;	}	*pfun = rad_accounting;	if (debug_flag) {		fr_printf_log("detail_recv: Read packet from %s\n", data->filename_work);		for (vp = packet->vps; vp; vp = vp->next) {			debug_pair(vp);		}	}	/*	 *	FIXME: many of these checks may not be necessary when	 *	reading from the detail file.	 *	 *	Try again later...	 */	if (!received_request(listener, packet, prequest,			      &data->detail_client)) {		rad_free(&packet);		data->state = STATE_NO_REPLY;	/* try again later */		return 0;	}	data->state = STATE_RUNNING;	return 1;}/* *	Free detail-specific stuff. */void detail_free(rad_listen_t *this){	listen_detail_t *data = this->data;	free(data->filename);	pairfree(&data->vps);	if (data->fp != NULL) fclose(data->fp);}int detail_print(rad_listen_t *this, char *buffer, size_t bufsize){	if (!this->server) {		return snprintf(buffer, bufsize, "%s",				((listen_detail_t *)(this->data))->filename);	}	return snprintf(buffer, bufsize, "detail file %s as server %s",			((listen_detail_t *)(this->data))->filename,			this->server);}int detail_encode(UNUSED rad_listen_t *this, UNUSED REQUEST *request){	/*	 *	We never encode responses "sent to" the detail file.	 */	return 0;}int detail_decode(UNUSED rad_listen_t *this, UNUSED REQUEST *request){	/*	 *	We never decode responses read from the detail file.	 */	return 0;}static const CONF_PARSER detail_config[] = {	{ "filename",   PW_TYPE_STRING_PTR,	  offsetof(listen_detail_t, filename), NULL,  NULL },	{ "load_factor",   PW_TYPE_INTEGER,	  offsetof(listen_detail_t, load_factor), NULL, Stringify(10)},	{ NULL, -1, 0, NULL, NULL }		/* end the list */};/* *	Parse a detail section. */int detail_parse(CONF_SECTION *cs, rad_listen_t *this){	int		rcode;	listen_detail_t *data;	RADCLIENT	*client;	char buffer[2048];	if (!this->data) {		this->data = rad_malloc(sizeof(*data));		memset(this->data, 0, sizeof(*data));	}	data = this->data;	data->delay_time = USEC;	rcode = cf_section_parse(cs, data, detail_config);	if (rcode < 0) {		cf_log_err(cf_sectiontoitem(cs), "Failed parsing listen section");		return -1;	}	if (!data->filename) {		cf_log_err(cf_sectiontoitem(cs), "No detail file specified in listen section");		return -1;	}	if ((data->load_factor < 1) || (data->load_factor > 100)) {		cf_log_err(cf_sectiontoitem(cs), "Load factor must be between 1 and 100");		return -1;	}	snprintf(buffer, sizeof(buffer), "%s.work", data->filename);	free(data->filename_work);	data->filename_work = strdup(buffer); /* FIXME: leaked */	data->vps = NULL;	data->fp = NULL;	data->state = STATE_UNOPENED;	/*	 *	Initialize the fake client.	 */	client = &data->detail_client;	memset(client, 0, sizeof(*client));	client->ipaddr.af = AF_INET;	client->ipaddr.ipaddr.ip4addr.s_addr = INADDR_NONE;	client->prefix = 0;	client->longname = client->shortname = data->filename;	client->secret = client->shortname;	client->nastype = strdup("none");	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -