📄 rlm_sqlippool.c
字号:
if (data->stop_clear == NULL || strlen(data->stop_clear) == 0) { radlog(L_ERR, "rlm_sqlippool: the 'stop-clear' statement must be set."); free(data); exit(0); } if (data->on_clear == NULL || strlen(data->on_clear) == 0) { radlog(L_ERR, "rlm_sqlippool: the 'on-clear' statement must be set."); free(data); exit(0); } if (data->off_clear == NULL || strlen(data->off_clear) == 0) { radlog(L_ERR, "rlm_sqlippool: the 'off-clear' statement must be set."); free(data); exit(0); } pool_name = cf_section_name2(conf); if (pool_name != NULL) data->pool_name = strdup(pool_name); else data->pool_name = strdup("ippool"); if ( !(data->sql_inst = (SQL_INST *) (find_module_instance(data->sql_instance_name))->insthandle) ) { radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name); free(data); exit(0); } sqlippool_initialize_sql(data); pthread_mutex_init(&data->dlock, NULL); *instance = data; return 0;}/* * Allocate an IP number from the pool. */static int sqlippool_postauth(void *instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; char allocation[MAX_STRING_LEN]; int allocation_len; uint32_t ip_allocation; VALUE_PAIR * vp; SQLSOCK * sqlsocket; long self = (long) pthread_self(); /* * If there is a Framed-IP-Address attribute in the reply do nothing */ if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) { DEBUG("rlm_sqlippool: Framed-IP-Address already exists"); return RLM_MODULE_NOOP; } if ((vp = pairfind(request->config_items, PW_POOL_NAME)) != NULL) { DEBUG("Value Of the Pool-Name is [%s] and its [%i] Chars \n", vp->strvalue, vp->length); pthread_mutex_lock(&data->dlock); strNcpy(data->pool_name, vp->strvalue, (vp->length + 1)); pthread_mutex_unlock(&data->dlock); } else { DEBUG("rlm_sqlippool: missing pool_name"); return RLM_MODULE_NOOP; } if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_sqlippool: unknown NAS-IP-Address"); return RLM_MODULE_NOOP; } if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) { DEBUG("rlm_sqlippool: unknown NAS-Port"); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->allocate_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->allocate_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * FIND */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), data->allocate_find, sqlsocket, instance, request, (char *) NULL, 0); radlog(L_INFO,"rlm_sqlippool: ip=[%s] len=%d", allocation, allocation_len); if (allocation_len == 0) { /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); DEBUG("rlm_sqlippool: IP number could not be allocated."); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_NOTFOUND; } ip_allocation = ip_addr(allocation); if (ip_allocation == INADDR_NONE) { /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); DEBUG("rlm_sqlippool: Invalid IP number [%s] returned from database query.", allocation); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_NOOP; } /* * UPDATE */ sqlippool_command(data->allocate_update, sqlsocket, instance, request, allocation, allocation_len); DEBUG("rlm_sqlippool: Allocated IP %s [%08x]", allocation, ip_allocation); if ((vp = paircreate(PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR)) == NULL) { radlog(L_ERR|L_CONS, "no memory"); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_NOOP; } vp->lvalue = ip_allocation; pairadd(&request->reply->vps, vp); /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_start(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) { DEBUG("rlm_ippool: Could not find port number in packet."); return RLM_MODULE_NOOP; } if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->start_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(data->start_update, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->start_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_alive(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) { DEBUG("rlm_ippool: Could not find port number in packet."); return RLM_MODULE_NOOP; } if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->alive_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(data->alive_update, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->alive_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_stop(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_PORT) == NULL) { DEBUG("rlm_ippool: Could not find port number in packet."); return RLM_MODULE_NOOP; } if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->stop_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->stop_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->stop_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_on(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->on_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->on_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->on_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_off(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->off_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->off_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->off_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}/* * Check for an Accounting-Stop * If we find one and we have allocated an IP to this nas/port combination, deallocate it. */static int sqlippool_accounting(void * instance, REQUEST * request){ VALUE_PAIR * vp; int acct_status_type; vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE); if (vp == NULL) { DEBUG("rlm_sqlippool: Could not find account status type in packet."); return RLM_MODULE_NOOP; } acct_status_type = vp->lvalue; switch (acct_status_type) { case PW_STATUS_START: return sqlippool_accounting_start(instance, request); case PW_STATUS_ALIVE: return sqlippool_accounting_alive(instance, request); case PW_STATUS_STOP: return sqlippool_accounting_stop(instance, request); case PW_STATUS_ACCOUNTING_ON: return sqlippool_accounting_on(instance, request); case PW_STATUS_ACCOUNTING_OFF: return sqlippool_accounting_off(instance, request); default: /* We don't care about any other accounting packet */ return RLM_MODULE_NOOP; }}static int sqlippool_detach(void *instance){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; free(data->sql_instance_name); free(data->pool_name); free(data->allocate_begin); free(data->allocate_clear); free(data->allocate_find); free(data->allocate_update); free(data->allocate_commit); free(data->allocate_rollback); free(data->start_begin); free(data->start_update); free(data->start_commit); free(data->start_rollback); free(data->alive_begin); free(data->alive_update); free(data->alive_commit); free(data->alive_rollback); free(data->stop_begin); free(data->stop_clear); free(data->stop_commit); free(data->stop_rollback); free(data->on_begin); free(data->on_clear); free(data->on_commit); free(data->on_rollback); free(data->off_begin); free(data->off_clear); free(data->off_commit); free(data->off_rollback); 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_sqlippool = { "SQL IP Pool", RLM_TYPE_THREAD_SAFE, /* type */ NULL, /* initialization */ sqlippool_instantiate, /* instantiation */ { NULL, /* authentication */ NULL, /* authorization */ NULL, /* preaccounting */ sqlippool_accounting, /* accounting */ NULL, /* checksimul */ NULL, /* pre-proxy */ NULL, /* post-proxy */ sqlippool_postauth /* post-auth */ }, sqlippool_detach, /* detach */ NULL, /* destroy */};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -