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

📄 rlm_ippool.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 2 页
字号:
		pthread_mutex_lock(&data->ip_mutex);		data_datum = gdbm_fetch(data->ip, key_datum);		pthread_mutex_unlock(&data->ip_mutex);		if (data_datum.dptr != NULL){			memcpy(&num, data_datum.dptr, sizeof(int));			free(data_datum.dptr);			if (num >0){				num--;				DEBUG("rlm_ippool: num: %d",num);				data_datum.dptr = (char *) &num;				data_datum.dsize = sizeof(int);				pthread_mutex_lock(&data->ip_mutex);				rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);				pthread_mutex_unlock(&data->ip_mutex);				if (rcode < 0) {					radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",							data->ip_index, gdbm_strerror(gdbm_errno));					return RLM_MODULE_FAIL;				}			}		}	}	else		DEBUG("rlm_ippool: Entry not found");	return RLM_MODULE_OK;}static int ippool_postauth(void *instance, REQUEST *request){	rlm_ippool_t *data = (rlm_ippool_t *) instance;	unsigned int port = 0;	int delete = 0;	int rcode;	int num = 0;	char nas[MAX_NAS_NAME_SIZE];	datum key_datum;	datum nextkey;	datum data_datum;	ippool_key key;	ippool_info entry;	VALUE_PAIR *vp;	char *cli = NULL;	char str[32];	/* quiet the compiler */	instance = instance;	request = request;	/* Check if Pool-Name attribute exists. If it exists check our name and	 * run only if they match	 */	if ((vp = pairfind(request->config_items, PW_POOL_NAME)) != NULL){		if (data->name == NULL || strcmp(data->name,vp->strvalue))			return RLM_MODULE_NOOP;	} else {		DEBUG("rlm_ippool: Could not find Pool-Name attribute.");		return RLM_MODULE_NOOP;	}	/*	 * Get the nas ip address	 * If not fail	 */	if ((vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS)) != NULL)		strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);	else{		if ((vp = pairfind(request->packet->vps, PW_NAS_IDENTIFIER)) != NULL)			strncpy(nas, vp->strvalue, MAX_NAS_NAME_SIZE - 1);		else{			DEBUG("rlm_ippool: Could not find nas information.");			return RLM_MODULE_NOOP;		}	}	/*	 * Find the caller id	 */	if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)		cli = vp->strvalue;	/*	 * Find the port	 * If not fail	 */	if ((vp = pairfind(request->packet->vps, PW_NAS_PORT)) != NULL)		port = vp->lvalue;	else{		DEBUG("rlm_ippool: Could not find port information.");		return RLM_MODULE_NOOP;	}	memset(key.nas,0,MAX_NAS_NAME_SIZE);	strncpy(key.nas,nas,MAX_NAS_NAME_SIZE -1 );	key.port = port;		DEBUG("rlm_ippool: Searching for an entry for nas/port: %s/%u",key.nas,key.port);	key_datum.dptr = (char *) &key;	key_datum.dsize = sizeof(ippool_key);	pthread_mutex_lock(&data->session_mutex);	data_datum = gdbm_fetch(data->gdbm, key_datum);	pthread_mutex_unlock(&data->session_mutex);	if (data_datum.dptr != NULL){		/*		 * If there is a corresponding entry in the database with active=1 it is stale.		 * Set active to zero		 */		memcpy(&entry, data_datum.dptr, sizeof(ippool_info));		free(data_datum.dptr);		if (entry.active){			DEBUG("rlm_ippool: Found a stale entry for ip/port: %s/%u",ip_ntoa(str,entry.ipaddr),port);			entry.active = 0;			data_datum.dptr = (char *) &entry;			data_datum.dsize = sizeof(ippool_info);			pthread_mutex_lock(&data->session_mutex);			rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);			pthread_mutex_unlock(&data->session_mutex);			if (rcode < 0) {				radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",					data->session_db, gdbm_strerror(gdbm_errno));				return RLM_MODULE_FAIL;			}			/* Decrease allocated count from the ip index */			key_datum.dptr = (char *) &entry.ipaddr;			key_datum.dsize = sizeof(uint32_t);			pthread_mutex_lock(&data->ip_mutex);			data_datum = gdbm_fetch(data->ip, key_datum);			pthread_mutex_unlock(&data->ip_mutex);			if (data_datum.dptr != NULL){				memcpy(&num, data_datum.dptr, sizeof(int));				free(data_datum.dptr);				if (num >0){					num--;					DEBUG("rlm_ippool: num: %d",num);					data_datum.dptr = (char *) &num;					data_datum.dsize = sizeof(int);					pthread_mutex_lock(&data->ip_mutex);					rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);					pthread_mutex_unlock(&data->ip_mutex);					if (rcode < 0) {						radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",								data->ip_index, gdbm_strerror(gdbm_errno));						return RLM_MODULE_FAIL;					}				}			}		}	}	/*	 * If there is a Framed-IP-Address attribute in the reply, check for override	 */	if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) {		if (data->override)		{			/* Override supplied Framed-IP-Address */			pairdelete(&request->reply->vps, PW_FRAMED_IP_ADDRESS);		} else {			/* Abort */			return RLM_MODULE_NOOP;		}	}	/*	 * Walk through the database searching for an active=0 entry.	 */	pthread_mutex_lock(&data->session_mutex);	key_datum = gdbm_firstkey(data->gdbm);	while(key_datum.dptr){		data_datum = gdbm_fetch(data->gdbm, key_datum);		if (data_datum.dptr){			memcpy(&entry,data_datum.dptr, sizeof(ippool_info));			free(data_datum.dptr);				/*		 	* If we find an entry for the same caller-id and nas with active=1		 	* then we use that for multilink (MPPP) to work properly.		 	*/			if (cli != NULL && strcmp(entry.cli,cli) == 0 && entry.active){				memcpy(&key,key_datum.dptr,sizeof(ippool_key));				if (!strcmp(key.nas,nas))					break;			}			if (entry.active == 0){				datum tmp;						tmp.dptr = (char *) &entry.ipaddr;				tmp.dsize = sizeof(uint32_t);				pthread_mutex_lock(&data->ip_mutex);				data_datum = gdbm_fetch(data->ip, tmp);				pthread_mutex_unlock(&data->ip_mutex);				/*				 * If we find an entry in the ip index and the number is zero (meaning				 * that we haven't allocated the same ip address to another nas/port pair)				 * or if we don't find an entry then delete the session entry so				 * that we can change the key (nas/port)				 * Else we don't delete the session entry since we haven't yet deallocated the				 * corresponding ip address and we continue our search.				 */				if (data_datum.dptr){					memcpy(&num,data_datum.dptr, sizeof(int));					free(data_datum.dptr);					if (num == 0){						delete = 1;						break;					}				}				else{					delete = 1;					break;				}			}		}		nextkey = gdbm_nextkey(data->gdbm, key_datum);		free(key_datum.dptr);		key_datum = nextkey;	}	pthread_mutex_unlock(&data->session_mutex);	/*	 * If we have found a free entry set active to 1 then add a Framed-IP-Address attribute to	 * the reply	 */	if (key_datum.dptr){		entry.active = 1;		data_datum.dptr = (char *) &entry;		data_datum.dsize = sizeof(ippool_info);		if (delete){			/*		 	 * Delete the entry so that we can change the key		 	 */			pthread_mutex_lock(&data->session_mutex);			gdbm_delete(data->gdbm, key_datum);			pthread_mutex_unlock(&data->session_mutex);		}		free(key_datum.dptr);		memset(key.nas,0,MAX_NAS_NAME_SIZE);		strncpy(key.nas,nas,MAX_NAS_NAME_SIZE - 1);		key.port = port;		key_datum.dptr = (char *) &key;		key_datum.dsize = sizeof(ippool_key);				DEBUG2("rlm_ippool: Allocating ip to nas/port: %s/%u",key.nas,key.port);		pthread_mutex_lock(&data->session_mutex);		rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);		pthread_mutex_unlock(&data->session_mutex);		if (rcode < 0) {			radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",				data->session_db, gdbm_strerror(gdbm_errno));			return RLM_MODULE_FAIL;		}		/* Increase the ip index count */		key_datum.dptr = (char *) &entry.ipaddr;		key_datum.dsize = sizeof(uint32_t);			pthread_mutex_lock(&data->ip_mutex);		data_datum = gdbm_fetch(data->ip, key_datum);		pthread_mutex_unlock(&data->ip_mutex);		if (data_datum.dptr){			memcpy(&num,data_datum.dptr,sizeof(int));			free(data_datum.dptr);		}		num++;		DEBUG("rlm_ippool: num: %d",num);		data_datum.dptr = (char *) &num;		data_datum.dsize = sizeof(int);		pthread_mutex_lock(&data->ip_mutex);		rcode = gdbm_store(data->ip, key_datum, data_datum, GDBM_REPLACE);		pthread_mutex_unlock(&data->ip_mutex);		if (rcode < 0) {			radlog(L_ERR, "rlm_ippool: Failed storing data to %s: %s",				data->ip_index, gdbm_strerror(gdbm_errno));			return RLM_MODULE_FAIL;		}					DEBUG("rlm_ippool: Allocated ip %s to client on nas %s,port %u",ip_ntoa(str,entry.ipaddr),				key.nas,port);		if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) {			radlog(L_ERR|L_CONS, "no memory");			return RLM_MODULE_NOOP;		}		vp->lvalue = entry.ipaddr;		ip_ntoa(vp->strvalue, vp->lvalue);		pairadd(&request->reply->vps, vp);		/*		 *	If there is no Framed-Netmask attribute in the		 *	reply, add one		 */		if (pairfind(request->reply->vps, PW_FRAMED_IP_NETMASK) == NULL) {			if ((vp = paircreate(PW_FRAMED_IP_NETMASK, PW_TYPE_IPADDR)) == NULL)				radlog(L_ERR|L_CONS, "no memory");			else {				vp->lvalue = ntohl(data->netmask);				ip_ntoa(vp->strvalue, vp->lvalue);				pairadd(&request->reply->vps, vp);			}		}	}	else{		DEBUG("rlm_ippool: No available ip addresses in pool.");		return RLM_MODULE_NOOP;	}	return RLM_MODULE_OK;}static int ippool_detach(void *instance){	rlm_ippool_t *data = (rlm_ippool_t *) instance;	gdbm_close(data->gdbm);	gdbm_close(data->ip);	free(data->session_db);	free(data->ip_index);	pthread_mutex_destroy(&data->session_mutex);	pthread_mutex_destroy(&data->ip_mutex);	free(instance);	return 0;}/* *	The module name should be the only globally exported symbol. *	That is, everything else should be 'static'. * *	If the module needs to temporarily modify it's instantiation *	data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. *	The server will then take care of ensuring that the module *	is single-threaded. */module_t rlm_ippool = {	"IPPOOL",		RLM_TYPE_THREAD_SAFE,		/* type */	NULL,				/* initialization */	ippool_instantiate,		/* instantiation */	{		NULL,			/* authentication */		NULL,		 	/* authorization */		NULL,			/* preaccounting */		ippool_accounting,	/* accounting */		NULL,			/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		ippool_postauth		/* post-auth */	},	ippool_detach,			/* detach */	NULL,				/* destroy */};

⌨️ 快捷键说明

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