📄 rlm_ippool.c
字号:
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 *) # 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 *) # 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 *) # 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 + -