radius_acct.c
来自「The Kannel Open Source WAP and SMS gatew」· C语言 代码 · 共 436 行 · 第 1/2 页
C
436 行
run_thread = 1; ss = cs = -1; /* create client binding, only if we have a remote server */ if (remote_host != NULL) { cs = udp_client_socket(); addr = udp_create_address(remote_host, remote_port); } /* create server binding */ ss = udp_bind(our_port, octstr_get_cstr(our_host)); /* make the server socket non-blocking */ fl = fcntl(ss, F_GETFL); fcntl(ss, F_SETFL, fl | O_NONBLOCK); if (ss == -1) panic(0, "RADIUS: Couldn't set up server socket for port %ld.", our_port); while (run_thread) { RADIUS_PDU *pdu, *r; Octstr *data, *rdata; Octstr *from_nas, *from_radius; if (read_available(ss, 100000) < 1) continue; /* get request from NAS */ if (udp_recvfrom(ss, &data, &from_nas) == -1) { if (errno == EAGAIN) /* No datagram available, don't block. */ continue; error(0, "RADIUS: Couldn't receive request data from NAS"); continue; } tmp = udp_get_ip(from_nas); info(0, "RADIUS: Got data from NAS <%s:%d>", octstr_get_cstr(tmp), udp_get_port(from_nas)); octstr_destroy(tmp); octstr_dump(data, 0); /* unpacking the RADIUS PDU */ pdu = radius_pdu_unpack(data); info(0, "RADIUS PDU type: %s", pdu->type_name); /* FIXME: XXX authenticator md5 check does not work?! */ //radius_authenticate_pdu(pdu, data, secret_nas); /* store to hash table if not present yet */ mutex_lock(radius_mutex); forward = update_tables(pdu); mutex_unlock(radius_mutex); /* create response PDU for NAS */ r = radius_pdu_create(0x05, pdu); /* * create response authenticator * code+identifier(req)+length+authenticator(req)+(attributes)+secret */ r->u.Accounting_Response.identifier = pdu->u.Accounting_Request.identifier; r->u.Accounting_Response.authenticator = octstr_duplicate(pdu->u.Accounting_Request.authenticator); /* pack response for NAS */ rdata = radius_pdu_pack(r); /* creates response autenticator in encoded PDU */ radius_authenticate_pdu(r, &rdata, secret_nas); /* * forward request to remote RADIUS server only if updated * and if we have a configured remote RADIUS server */ if ((remote_host != NULL) && forward) { if (udp_sendto(cs, data, addr) == -1) { error(0, "RADIUS: Couldn't send to remote RADIUS <%s:%ld>.", octstr_get_cstr(remote_host), remote_port); } else if (udp_recvfrom(cs, &data, &from_radius) == -1) { error(0, "RADIUS: Couldn't receive from remote RADIUS <%s:%ld>.", octstr_get_cstr(remote_host), remote_port); } else { info(0, "RADIUS: Got data from remote RADIUS <%s:%d>", octstr_get_cstr(udp_get_ip(from_radius)), udp_get_port(from_radius)); octstr_dump(data, 0); /* XXX unpack the response PDU and check if the response * authenticator is valid */ } } /* send response to NAS */ if (udp_sendto(ss, rdata, from_nas) == -1) error(0, "RADIUS: Couldn't send response data to NAS <%s:%d>.", octstr_get_cstr(udp_get_ip(from_nas)), udp_get_port(from_nas)); radius_pdu_destroy(pdu); radius_pdu_destroy(r); octstr_destroy(rdata); octstr_destroy(data); octstr_destroy(from_nas); debug("radius.proxy", 0, "RADIUS: Mapping table contains %ld elements", dict_key_count(radius_table)); debug("radius.proxy", 0, "RADIUS: Session table contains %ld elements", dict_key_count(session_table)); debug("radius.proxy", 0, "RADIUS: Client table contains %ld elements", dict_key_count(client_table)); } octstr_destroy(addr);}/************************************************************************* * Public functions: init, shutdown, mapping. */Octstr *radius_acct_get_msisdn(Octstr *client_ip){ Octstr *m, *r; char *uf; /* if no proxy thread is running, then pass NULL as result */ if (radius_table == NULL || client_ip == NULL) return NULL; mutex_lock(radius_mutex); m = dict_get(radius_table, client_ip); mutex_unlock(radius_mutex); r = m ? octstr_duplicate(m) : NULL; /* apply number normalization */ uf = unified_prefix ? octstr_get_cstr(unified_prefix) : NULL; normalize_number(uf, &r); return r;}void radius_acct_init(CfgGroup *grp){ unsigned long nas_ports = 0; /* get configured parameters */ if ((our_host = cfg_get(grp, octstr_imm("our-host"))) == NULL) { our_host = octstr_create("0.0.0.0"); } if ((remote_host = cfg_get(grp, octstr_imm("remote-host"))) != NULL) { cfg_get_integer(&remote_port, grp, octstr_imm("remote-port")); if ((secret_radius = cfg_get(grp, octstr_imm("secret-radius"))) == NULL) { panic(0, "RADIUS: No shared secret `secret-radius' for remote RADIUS in `radius-acct' provided."); } } cfg_get_integer(&our_port, grp, octstr_imm("our-port")); if ((cfg_get_integer(&nas_ports, grp, octstr_imm("nas-ports"))) == -1) { nas_ports = RADIUS_NAS_PORTS; } if ((secret_nas = cfg_get(grp, octstr_imm("secret-nas"))) == NULL) { panic(0, "RADIUS: No shared secret `secret-nas' for NAS in `radius-acct' provided."); } unified_prefix = cfg_get(grp, octstr_imm("unified-prefix")); info(0, "RADIUS: local RADIUS accounting proxy at <%s:%ld>", octstr_get_cstr(our_host), our_port); if (remote_host == NULL) { info(0, "RADIUS: remote RADIUS accounting server is absent"); } else { info(0, "RADIUS: remote RADIUS accounting server at <%s:%ld>", octstr_get_cstr(remote_host), remote_port); } info(0, "RADIUS: initializing internal hash tables with %ld buckets.", nas_ports); radius_mutex = mutex_create(); /* init hash tables */ radius_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); session_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); client_table = dict_create(nas_ports, (void (*)(void *))octstr_destroy); gwthread_create(proxy_thread, NULL);}void radius_acct_shutdown(void){ if (radius_mutex == NULL) /* haven't init'ed at all */ return ; mutex_lock(radius_mutex); run_thread = 0; mutex_unlock(radius_mutex); gwthread_join_every(proxy_thread); dict_destroy(radius_table); dict_destroy(session_table); dict_destroy(client_table); mutex_destroy(radius_mutex); octstr_destroy(our_host); octstr_destroy(remote_host); octstr_destroy(secret_nas); octstr_destroy(secret_radius); octstr_destroy(unified_prefix); info(0, "RADIUS: accounting proxy stopped.");}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?