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

📄 rlm_sqlhpwippool.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!sqlsock) {		nvp_log(__LINE__, data, L_ERR,		        "sqlhpwippool_postauth(): error while requesting an SQL socket");		return RLM_MODULE_FAIL;	}	/* get connection id as temporary unique integer */	if (nvp_select(__LINE__, data, sqlsock, "SELECT CONNECTION_ID()") < 1) {		nvp_log(__LINE__, data, L_ERR, "sqlhpwippool_postauth(): WTF ;-)!");		nvp_select_finish(data, sqlsock);		sql_release_socket(data->sqlinst, sqlsock);		return RLM_MODULE_FAIL;	}	connid = strtoul(sqlsock->row[0], (char **) NULL, 10);	nvp_select_finish(data, sqlsock);	/* synchronize with radacct db, if needed */	if (++data->sincesync >= data->syncafter#ifdef HAVE_PTHREAD_D	    && (pthread_mutex_trylock(&data->mutex)) == 0#endif	   ) {		int r;		data->sincesync = 0;		nvp_log(__LINE__, data, L_DBG,		        "sqlhpwippool_postauth(): syncing with radacct table");		r = (nvp_freeclosed(data, sqlsock) && nvp_syncfree(data, sqlsock));#ifdef HAVE_PTHREAD_D		pthread_mutex_unlock(&data->mutex);#endif		if (!r) {			nvp_log(__LINE__, data, L_ERR,			        "sqlhpwippool_postauth(): synchronization failed");			sql_release_socket(data->sqlinst, sqlsock);			return RLM_MODULE_FAIL;		}	}	for (s_gid = 0; s_gid < RLM_NETVIM_MAX_ROWS && !(ip.s_addr); s_gid++) {		nvp_log(__LINE__, data, L_DBG,		        "sqlhpwippool_postauth(): selecting gid on position %lu",		        s_gid);		/* find the most specific group which NAS belongs to */		switch (nvp_select(__LINE__, data, sqlsock,		       "SELECT `host_groups`.`gid` "		       	"FROM "		       		"`%s`.`host_groups`, "		       		"`%1$s`.`gid_ip`, "		       		"`%1$s`.`ids` "		       	"WHERE "		       		"`host_groups`.`gid` = `ids`.`id` AND "		       		"`ids`.`enabled` = 1 AND "		       		"`host_groups`.`gid` = `gid_ip`.`gid` AND "		       		"%lu BETWEEN `gid_ip`.`ip_start` AND `gid_ip`.`ip_stop` "		       	"ORDER BY (`gid_ip`.`ip_stop` - `gid_ip`.`ip_start`) ASC "		       	"LIMIT %lu, 1",		       data->db_name, nasip, s_gid)) {			case -1:				nvp_log(__LINE__, data, L_ERR,				        "sqlhpwippool_postauth(): couldn't find "				        "any more matching host groups");				goto end_gid;                  /* exit the main loop */			case 0:				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;		}		/* store the group ID and free memory occupied by results */		gid = strtoul(sqlsock->row[0], (char **) NULL, 10);		nvp_select_finish(data, sqlsock);		for (s_prio = 0; s_prio < RLM_NETVIM_MAX_ROWS && !(ip.s_addr); s_prio++) {			nvp_log(__LINE__, data, L_DBG,			        "sqlhpwippool_postauth(): selecting prio on position %lu",			        s_prio);			/* prepare to search for best fit pool */			switch (nvp_select(__LINE__, data, sqlsock,			        "SELECT "			        	"`ip_pools`.`prio`, "			        	"SUM(`ip_pools`.`weight`) AS `weights_sum`, "			        	"(SUM(`ip_pools`.`total`) - "			        		"SUM(`ip_pools`.`free`)) AS `used_sum` "			        	"FROM "			        		"`%s`.`ip_pools`, "			        		"`%1$s`.`ids`, "			        	 	"`%1$s`.`pool_names` "			        	"WHERE "			        		"`ip_pools`.`gid` = %lu AND "			        		"`ids`.`id` = `ip_pools`.`pid` AND "			        		"`ids`.`enabled` = 1 AND "			        		"`pool_names`.`pnid` = `ip_pools`.`pnid` AND "			        		"`pool_names`.`name` = '%s' AND "			        		"`ip_pools`.`free` > 0 "			        	"GROUP BY `prio` "			        	"ORDER BY `prio` ASC "			        	"LIMIT %lu, 1",			        data->db_name, gid, pname, s_prio)) {				case -1:					nvp_log(__LINE__, data, L_DBG,					        "sqlhpwippool_postauth(): couldn't find "					        "any more matching pools for gid = %u",					        gid);					goto end_prio;               /* select next gid */				case 0:					sql_release_socket(data->sqlinst, sqlsock);					return RLM_MODULE_FAIL;			}			/* store the prio and weights sum */			prio = strtol(sqlsock->row[0], (char **) NULL, 10);			weights_sum = strtoul(sqlsock->row[1], (char **) NULL, 10);			used_sum = strtoul(sqlsock->row[2], (char **) NULL, 10);			/* free memory */			nvp_select_finish(data, sqlsock);			for (s_pid = 0; s_pid < RLM_NETVIM_MAX_ROWS && !(ip.s_addr); s_pid++) {				nvp_log(__LINE__, data, L_DBG,				        "sqlhpwippool_postauth(): selecting PID on position %lu",				        s_pid);				/* search for best fit pool */				switch (nvp_select(__LINE__, data, sqlsock,				        "SELECT "				        	"`ip_pools`.`pid`, "				        	"`ip_pools`.`ip_start`, "				        	"`ip_pools`.`ip_stop` "				        	"FROM "				        		"`%s`.`ip_pools`, "				        		"`%1$s`.`ids`, "				        		"`%1$s`.`pool_names` "				        	"WHERE "				        		"`ip_pools`.`gid` = %lu AND "				        		"`ids`.`id` = `ip_pools`.`pid` AND "				        		"`ids`.`enabled` = 1 AND "				        		"`pool_names`.`pnid` = `ip_pools`.`pnid` AND "				        		"`pool_names`.`name` = '%s' AND "				        		"`ip_pools`.`free` > 0 AND "				        		"`prio` = %ld "				        	"ORDER BY (`weight`/%lu.0000 - (`total` - `free`)/%lu) DESC "				        	"LIMIT %lu, 1",				        data->db_name, gid, pname, prio,				        weights_sum, used_sum, s_pid)) {					case -1:						nvp_log(__LINE__, data, L_DBG,						        "sqlhpwippool_postauth(): couldn't find any more "						        "matching pools of prio = %ld for gid = %lu",						        prio, gid);						goto end_pid;              /* select next prio */					case 0:						sql_release_socket(data->sqlinst, sqlsock);						return RLM_MODULE_FAIL;				}				/* store the data and free memory occupied by results */				pid = strtoul(sqlsock->row[0], (char **) NULL, 10);				ip_start = strtoul(sqlsock->row[1], (char **) NULL, 10);				ip_stop = strtoul(sqlsock->row[2], (char **) NULL, 10);				nvp_select_finish(data, sqlsock);				/* reserve an IP address */				if (!nvp_query(__LINE__, data, sqlsock,				    "UPDATE `%s`.`ips` "				    	"SET "				    		"`pid` = %lu, "				    		"`rsv_since` = NOW(), "				    		"`rsv_by` = '" RLM_NETVIM_TMP_PREFIX "%lu', "				    		"`rsv_until` = NOW() + INTERVAL %d SECOND "				    	"WHERE "				    		"`ip` BETWEEN %lu AND %lu AND "				    		"("				    			"`pid` IS NULL OR "				    			"(`rsv_until` > 0 AND `rsv_until` < NOW())"				    		") "				    	"ORDER BY RAND() "				    	"LIMIT 1",				    data->db_name, pid, connid, data->freeafter, ip_start, ip_stop)) {					sql_release_socket(data->sqlinst, sqlsock);					return RLM_MODULE_FAIL;				}				else {					nvp_finish(data, sqlsock);				}				/* select assigned IP address */				switch (nvp_select(__LINE__, data, sqlsock,				        "SELECT `ip` "				        	"FROM `%s`.`ips` "				        	"WHERE `rsv_by` = '" RLM_NETVIM_TMP_PREFIX "%lu' "				        	"ORDER BY `rsv_since` DESC "				        	"LIMIT 1",				        data->db_name, connid)) {					case -1:						nvp_log(__LINE__, data, L_ERR,						        "sqlhpwippool_postauth(): couldn't reserve an IP address "						        "from pool of pid = %lu (prio = %ld, gid = %lu)",						        pid, prio, gid);						continue;                            /* select next pid */					case 0:						sql_release_socket(data->sqlinst, sqlsock);						return RLM_MODULE_FAIL;				}				/* update free IPs count */				if (!nvp_query(__LINE__, data, sqlsock,				    "UPDATE `%s`.`ip_pools` "				    	"SET "				    		"`free` = `free` - 1 "				    	"WHERE "				    		"`pid` = %lu "			    	"LIMIT 1",				    data->db_name, pid)) {					sql_release_socket(data->sqlinst, sqlsock);					return RLM_MODULE_FAIL;				}				else {					nvp_finish(data, sqlsock);				}				/* get assigned IP and free memory */				ip.s_addr = htonl(strtoul(sqlsock->row[0], (char **) NULL, 10));				nvp_select_finish(data, sqlsock);			} /* pid */end_pid: continue;           /* stupid */		} /* prio */end_prio: continue;          /* stupid */	} /* gid */end_gid:	/* release SQL socket */	sql_release_socket(data->sqlinst, sqlsock);	/* no free IP address found */	if (!ip.s_addr) {		nvp_log(__LINE__, data, L_INFO,		        "sqlhpwippool_postauth(): no free IP address found!");		if (data->nofreefail) {			nvp_log(__LINE__, data, L_DBG, "sqlhpwippool_postauth(): rejecting user");			return RLM_MODULE_REJECT;		}		else {			nvp_log(__LINE__, data, L_DBG, "sqlhpwippool_postauth(): exiting");			return RLM_MODULE_NOOP;		}	}	/* add IP address to reply packet */	vp = radius_paircreate(request, &request->reply->vps,			       PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR);	vp->vp_ipaddr = ip.s_addr;	nvp_log(__LINE__, data, L_DBG, "sqlhpwippool_postauth(): returning %s",	        inet_ntoa(ip));	return RLM_MODULE_OK;}static int sqlhpwippool_accounting(void *instance, REQUEST *request){	VALUE_PAIR *vp;	SQLSOCK *sqlsock;	struct in_addr nasip;      /* NAS IP */	unsigned char *sessid;     /* unique session id */	char nasipstr[16];         /* NAS IP in string format */	uint32_t framedip = 0;     /* client's IP, host byte order */	uint32_t acct_type;	rlm_sqlhpwippool_t *data = (rlm_sqlhpwippool_t *) instance;	/* if no unique session ID, don't even try */	vp = pairfind(request->packet->vps, PW_ACCT_UNIQUE_SESSION_ID);	if (vp) {		sessid = vp->vp_strvalue;	}	else {		nvp_log(__LINE__, data, L_ERR,		        "sqlhpwippool_accounting(): unique session ID not found");		return RLM_MODULE_FAIL;	}	vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE);	if (vp) {		acct_type = vp->vp_integer;	}	else {		nvp_log(__LINE__, data, L_ERR, "sqlhpwippool_accounting(): "		                               "couldn't find type of accounting packet");		return RLM_MODULE_FAIL;	}	if (!(acct_type == PW_STATUS_START ||	      acct_type == PW_STATUS_ALIVE ||	      acct_type == PW_STATUS_STOP  ||	      acct_type == PW_STATUS_ACCOUNTING_OFF ||	      acct_type == PW_STATUS_ACCOUNTING_ON)) {		return RLM_MODULE_NOOP;	}	/* connect to database */	sqlsock = sql_get_socket(data->sqlinst);	if (!sqlsock) {		nvp_log(__LINE__, data, L_ERR,		        "sqlhpwippool_accounting(): couldn't connect to database");		return RLM_MODULE_FAIL;	}	switch (acct_type) {		case PW_STATUS_START:		case PW_STATUS_ALIVE:			vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS);			if (!vp) {				nvp_log(__LINE__, data, L_ERR, "sqlhpwippool_accounting(): no framed IP");				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;			}			framedip = ntohl(vp->vp_ipaddr);			if (!nvp_query(__LINE__, data, sqlsock,			    "UPDATE `%s`.`ips` "			    	"SET "			    		"`rsv_until` = 0, "			    		"`rsv_by` = '%s' "			    	"WHERE `ip` = %lu",			    data->db_name, sessid, framedip)) {				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;			}			nvp_finish(data, sqlsock);			break;		case PW_STATUS_STOP:			if (!nvp_query(__LINE__, data, sqlsock,			    "UPDATE `%s`.`ips`, `%1$s`.`ip_pools` "			    	"SET "			    		"`ips`.`rsv_until` = NOW() + INTERVAL %u SECOND, "			    		"`ip_pools`.`free` = `ip_pools`.`free` + 1 "			    	"WHERE "			    		"`ips`.`rsv_by` = '%s' AND "			    		"`ips`.`ip` BETWEEN `ip_pools`.`ip_start` AND `ip_pools`.`ip_stop`",			    data->db_name, data->freeafter, sessid)) {				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;			}			nvp_finish(data, sqlsock);		break;		case PW_STATUS_ACCOUNTING_OFF:		case PW_STATUS_ACCOUNTING_ON:			vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS);			if (!vp) {				nvp_log(__LINE__, data, L_ERR, "sqlhpwippool_accounting(): no NAS IP");				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;			}			nasip.s_addr = vp->vp_ipaddr;			strncpy(nasipstr, inet_ntoa(nasip), sizeof(nasipstr) - 1);			nasipstr[sizeof(nasipstr)] = 0;			if (!nvp_query(__LINE__, data, sqlsock,			    "UPDATE `%s`.`ips`, `radacct` "			    	"SET `ips`.`rsv_until` = NOW() + INTERVAL %u SECOND "			    	"WHERE "			    		"`radacct`.`nasipaddress` = '%s' AND "			    		"`ips`.`rsv_by` = `radacct`.`acctuniqueid`",			    data->db_name, data->freeafter, nasipstr)) {				sql_release_socket(data->sqlinst, sqlsock);				return RLM_MODULE_FAIL;			}			nvp_finish(data, sqlsock);			break;	}	sql_release_socket(data->sqlinst, sqlsock);	return RLM_MODULE_OK;}module_t rlm_sqlhpwippool = {	RLM_MODULE_INIT,	"sqlhpwippool",			/* name */	RLM_TYPE_THREAD_SAFE,		/* type */	sqlhpwippool_instantiate,	/* instantiation */	sqlhpwippool_detach,		/* detach */	{		NULL,			/* authentication */		NULL,			/* authorization */		NULL,			/* preaccounting */		sqlhpwippool_accounting,/* accounting */		NULL,			/* checksimul */		NULL,			/* pre-proxy */		NULL,			/* post-proxy */		sqlhpwippool_postauth	/* post-auth */	},};

⌨️ 快捷键说明

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