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 + -
显示快捷键?