00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00046 #include <stdio.h>
00047 #include <time.h>
00048
00049 #include "../../dprint.h"
00050 #include "../../error.h"
00051 #include "../../mem/mem.h"
00052 #include "../../usr_avp.h"
00053 #include "../../lib/srdb1/db.h"
00054 #include "../../parser/hf.h"
00055 #include "../../parser/msg_parser.h"
00056 #include "../../parser/parse_from.h"
00057 #include "../../parser/digest/digest.h"
00058 #include "../../modules/tm/t_funcs.h"
00059 #include "acc_mod.h"
00060 #include "acc.h"
00061 #include "acc_extra.h"
00062 #include "acc_logic.h"
00063 #include "acc_api.h"
00064
00065 #ifdef RAD_ACC
00066 #include "../../lib/kcore/radius.h"
00067 #endif
00068
00069 #ifdef DIAM_ACC
00070 #include "diam_dict.h"
00071 #include "diam_message.h"
00072 #include "diam_tcp.h"
00073 #endif
00074
00075 extern struct acc_extra *log_extra;
00076 extern struct acc_extra *leg_info;
00077 extern struct acc_enviroment acc_env;
00078
00079 #ifdef RAD_ACC
00080 extern struct acc_extra *rad_extra;
00081 #endif
00082
00083 #ifdef DIAM_ACC
00084 extern char *diameter_client_host;
00085 extern int diameter_client_port;
00086 extern struct acc_extra *dia_extra;
00087 #endif
00088
00089 #ifdef SQL_ACC
00090 static db_func_t acc_dbf;
00091 static db1_con_t* db_handle=0;
00092 extern struct acc_extra *db_extra;
00093 extern int acc_db_insert_mode;
00094 #endif
00095
00096
00097
00098 static str val_arr[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
00099 static int int_arr[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
00100 static char type_arr[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
00101
00102
00103
00104
00105 #define get_ft_body( _ft_hdr) \
00106 ((struct to_body*)_ft_hdr->parsed)
00107
00108 #define SET_EMPTY_VAL(_i) \
00109 do { \
00110 c_vals[_i].s = 0; \
00111 c_vals[_i].len = 0; \
00112 } while(0)
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int core2strar(struct sip_msg *req, str *c_vals, int *i_vals, char *t_vals)
00123 {
00124 struct to_body *ft_body;
00125 struct hdr_field *from;
00126 struct hdr_field *to;
00127
00128
00129 c_vals[0] = get_cseq(req)->method;
00130 t_vals[0] = TYPE_STR;
00131
00132
00133 if (req->msg_flags&FL_REQ_UPSTREAM) {
00134 LM_DBG("the flag UPSTREAM is set -> swap F/T\n"); \
00135 from = acc_env.to;
00136 to = req->from;
00137 } else {
00138 from = req->from;
00139 to = acc_env.to;
00140 }
00141
00142 if (from && (ft_body=get_ft_body(from)) && ft_body->tag_value.len) {
00143 c_vals[1] = ft_body->tag_value;
00144 t_vals[1] = TYPE_STR;
00145 } else {
00146 SET_EMPTY_VAL(1);
00147 t_vals[1] = TYPE_NULL;
00148 }
00149
00150 if (to && (ft_body=get_ft_body(to)) && ft_body->tag_value.len) {
00151 c_vals[2] = ft_body->tag_value;
00152 t_vals[2] = TYPE_STR;
00153 } else {
00154 SET_EMPTY_VAL(2);
00155 t_vals[2] = TYPE_NULL;
00156 }
00157
00158
00159 if (req->callid && req->callid->body.len) {
00160 c_vals[3] = req->callid->body;
00161 t_vals[3] = TYPE_STR;
00162 } else {
00163 SET_EMPTY_VAL(3);
00164 t_vals[3] = TYPE_NULL;
00165 }
00166
00167
00168 c_vals[4] = acc_env.code_s;
00169 i_vals[4] = acc_env.code;
00170 t_vals[4] = TYPE_INT;
00171
00172
00173 c_vals[5] = acc_env.reason;
00174 t_vals[5] = TYPE_STR;
00175
00176 acc_env.ts = time(NULL);
00177 return ACC_CORE_LEN;
00178 }
00179
00180
00181
00182
00183
00184
00185 static str log_attrs[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
00186
00187 #define SET_LOG_ATTR(_n,_atr) \
00188 do { \
00189 log_attrs[_n].s=A_##_atr; \
00190 log_attrs[_n].len=A_##_atr##_LEN; \
00191 n++; \
00192 } while(0)
00193
00194 void acc_log_init(void)
00195 {
00196 struct acc_extra *extra;
00197 int n;
00198
00199 n = 0;
00200
00201
00202 SET_LOG_ATTR(n,METHOD);
00203 SET_LOG_ATTR(n,FROMTAG);
00204 SET_LOG_ATTR(n,TOTAG);
00205 SET_LOG_ATTR(n,CALLID);
00206 SET_LOG_ATTR(n,CODE);
00207 SET_LOG_ATTR(n,STATUS);
00208
00209
00210 for(extra=log_extra; extra ; extra=extra->next)
00211 log_attrs[n++] = extra->name;
00212
00213
00214 for( extra=leg_info ; extra ; extra=extra->next)
00215 log_attrs[n++] = extra->name;
00216 }
00217
00218
00219 int acc_log_request( struct sip_msg *rq)
00220 {
00221 static char log_msg[MAX_SYSLOG_SIZE];
00222 static char *log_msg_end=log_msg+MAX_SYSLOG_SIZE-2;
00223 char *p;
00224 int n;
00225 int m;
00226 int i;
00227
00228
00229 m = core2strar( rq, val_arr, int_arr, type_arr);
00230
00231
00232 m += extra2strar( log_extra, rq, val_arr+m, int_arr+m, type_arr+m);
00233
00234 for ( i=0,p=log_msg ; i<m ; i++ ) {
00235 if (p+1+log_attrs[i].len+1+val_arr[i].len >= log_msg_end) {
00236 LM_WARN("acc message too long, truncating..\n");
00237 p = log_msg_end;
00238 break;
00239 }
00240 *(p++) = A_SEPARATOR_CHR;
00241 memcpy(p, log_attrs[i].s, log_attrs[i].len);
00242 p += log_attrs[i].len;
00243 *(p++) = A_EQ_CHR;
00244 memcpy(p, val_arr[i].s, val_arr[i].len);
00245 p += val_arr[i].len;
00246 }
00247
00248
00249 if ( leg_info ) {
00250 n = legs2strar(leg_info,rq,val_arr+m,int_arr+m,type_arr+m, 1);
00251 do {
00252 for (i=m; i<m+n; i++) {
00253 if (p+1+log_attrs[i].len+1+val_arr[i].len >= log_msg_end) {
00254 LM_WARN("acc message too long, truncating..\n");
00255 p = log_msg_end;
00256 break;
00257 }
00258 *(p++) = A_SEPARATOR_CHR;
00259 memcpy(p, log_attrs[i].s, log_attrs[i].len);
00260 p += log_attrs[i].len;
00261 *(p++) = A_EQ_CHR;
00262 memcpy(p, val_arr[i].s, val_arr[i].len);
00263 p += val_arr[i].len;
00264 }
00265 }while (p!=log_msg_end && (n=legs2strar(leg_info,rq,val_arr+m,
00266 int_arr+m,type_arr+m,
00267 0))!=0);
00268 }
00269
00270
00271 *(p++) = '\n';
00272 *(p++) = 0;
00273
00274 LM_GEN2(log_facility, log_level, "%.*stimestamp=%lu%s",
00275 acc_env.text.len, acc_env.text.s,(unsigned long) acc_env.ts, log_msg);
00276
00277 return 1;
00278 }
00279
00280
00281
00282
00283
00284
00285 #ifdef SQL_ACC
00286
00287
00288 static db_key_t db_keys[ACC_CORE_LEN+1+MAX_ACC_EXTRA+MAX_ACC_LEG];
00289 static db_val_t db_vals[ACC_CORE_LEN+1+MAX_ACC_EXTRA+MAX_ACC_LEG];
00290
00291
00292 static void acc_db_init_keys(void)
00293 {
00294 struct acc_extra *extra;
00295 int time_idx;
00296 int i;
00297 int n;
00298
00299
00300 n = 0;
00301
00302 db_keys[n++] = &acc_method_col;
00303 db_keys[n++] = &acc_fromtag_col;
00304 db_keys[n++] = &acc_totag_col;
00305 db_keys[n++] = &acc_callid_col;
00306 db_keys[n++] = &acc_sipcode_col;
00307 db_keys[n++] = &acc_sipreason_col;
00308 db_keys[n++] = &acc_time_col;
00309 time_idx = n-1;
00310
00311
00312 for(extra=db_extra; extra ; extra=extra->next)
00313 db_keys[n++] = &extra->name;
00314
00315
00316 for( extra=leg_info ; extra ; extra=extra->next)
00317 db_keys[n++] = &extra->name;
00318
00319
00320 for(i=0; i<n; i++) {
00321 VAL_TYPE(db_vals+i)=DB1_STR;
00322 VAL_NULL(db_vals+i)=0;
00323 }
00324 VAL_TYPE(db_vals+time_idx)=DB1_DATETIME;
00325 }
00326
00327
00328
00329
00330 int acc_db_init(const str* db_url)
00331 {
00332 if (db_bind_mod(db_url, &acc_dbf)<0){
00333 LM_ERR("bind_db failed\n");
00334 return -1;
00335 }
00336
00337
00338 if (!DB_CAPABILITY(acc_dbf, DB_CAP_INSERT)) {
00339 LM_ERR("database module does not implement insert function\n");
00340 return -1;
00341 }
00342
00343 acc_db_init_keys();
00344
00345 return 0;
00346 }
00347
00348
00349
00350
00351 int acc_db_init_child(const str *db_url)
00352 {
00353 db_handle=acc_dbf.init(db_url);
00354 if (db_handle==0){
00355 LM_ERR("unable to connect to the database\n");
00356 return -1;
00357 }
00358 return 0;
00359 }
00360
00361
00362
00363 void acc_db_close(void)
00364 {
00365 if (db_handle && acc_dbf.close)
00366 acc_dbf.close(db_handle);
00367 }
00368
00369
00370 int acc_db_request( struct sip_msg *rq)
00371 {
00372 int m;
00373 int n;
00374 int i;
00375
00376
00377 m = core2strar( rq, val_arr, int_arr, type_arr );
00378
00379 for(i=0; i<m; i++)
00380 VAL_STR(db_vals+i) = val_arr[i];
00381
00382 VAL_TIME(db_vals+(m++)) = acc_env.ts;
00383
00384
00385 m += extra2strar( db_extra, rq, val_arr+m, int_arr+m, type_arr+m);
00386
00387 for( i++ ; i<m; i++)
00388 VAL_STR(db_vals+i) = val_arr[i];
00389
00390 if (acc_dbf.use_table(db_handle, &acc_env.text) < 0) {
00391 LM_ERR("error in use_table\n");
00392 return -1;
00393 }
00394
00395
00396 if ( !leg_info ) {
00397 if(acc_db_insert_mode==1 && acc_dbf.insert_delayed!=NULL) {
00398 if (acc_dbf.insert_delayed(db_handle, db_keys, db_vals, m) < 0) {
00399 LM_ERR("failed to insert delayed into database\n");
00400 return -1;
00401 }
00402 } else {
00403 if (acc_dbf.insert(db_handle, db_keys, db_vals, m) < 0) {
00404 LM_ERR("failed to insert into database\n");
00405 return -1;
00406 }
00407 }
00408 } else {
00409 n = legs2strar(leg_info,rq,val_arr+m,int_arr+m,type_arr+m,1);
00410 do {
00411 for (i=m; i<m+n; i++)
00412 VAL_STR(db_vals+i)=val_arr[i];
00413 if(acc_db_insert_mode==1 && acc_dbf.insert_delayed!=NULL) {
00414 if(acc_dbf.insert_delayed(db_handle,db_keys,db_vals,m+n)<0) {
00415 LM_ERR("failed to insert delayed into database\n");
00416 return -1;
00417 }
00418 } else {
00419 if (acc_dbf.insert(db_handle, db_keys, db_vals, m+n) < 0) {
00420 LM_ERR("failed to insert into database\n");
00421 return -1;
00422 }
00423 }
00424 }while ( (n=legs2strar(leg_info,rq,val_arr+m,int_arr+m,
00425 type_arr+m,0))!=0 );
00426 }
00427
00428 return 1;
00429 }
00430
00431 #endif
00432
00433
00434
00435 #if defined(RAD_ACC) || defined (DIAM_ACC)
00436 #ifndef UINT4
00437 #define UINT4 uint32_t
00438 #endif
00439 inline static UINT4 phrase2code(str *phrase)
00440 {
00441 UINT4 code;
00442 int i;
00443
00444 if (phrase->len<3) return 0;
00445 code=0;
00446 for (i=0;i<3;i++) {
00447 if (!(phrase->s[i]>='0' && phrase->s[i]<'9'))
00448 return 0;
00449 code=code*10+phrase->s[i]-'0';
00450 }
00451 return code;
00452 }
00453 #endif
00454
00455
00456
00457
00458
00459 #ifdef RAD_ACC
00460 enum { RA_ACCT_STATUS_TYPE=0, RA_SERVICE_TYPE, RA_SIP_RESPONSE_CODE,
00461 RA_SIP_METHOD, RA_TIME_STAMP, RA_STATIC_MAX};
00462 enum {RV_STATUS_START=0, RV_STATUS_STOP, RV_STATUS_ALIVE, RV_STATUS_FAILED,
00463 RV_SIP_SESSION, RV_STATIC_MAX};
00464 static struct attr
00465 rd_attrs[RA_STATIC_MAX+ACC_CORE_LEN-2+MAX_ACC_EXTRA+MAX_ACC_LEG];
00466 static struct val rd_vals[RV_STATIC_MAX];
00467
00468 int init_acc_rad(char *rad_cfg, int srv_type)
00469 {
00470 int n;
00471
00472 memset(rd_attrs, 0, sizeof(rd_attrs));
00473 memset(rd_vals, 0, sizeof(rd_vals));
00474 rd_attrs[RA_ACCT_STATUS_TYPE].n = "Acct-Status-Type";
00475 rd_attrs[RA_SERVICE_TYPE].n = "Service-Type";
00476 rd_attrs[RA_SIP_RESPONSE_CODE].n = "Sip-Response-Code";
00477 rd_attrs[RA_SIP_METHOD].n = "Sip-Method";
00478 rd_attrs[RA_TIME_STAMP].n = "Event-Timestamp";
00479 n = RA_STATIC_MAX;
00480
00481 rd_attrs[n++].n = "Sip-From-Tag";
00482 rd_attrs[n++].n = "Sip-To-Tag";
00483 rd_attrs[n++].n = "Acct-Session-Id";
00484
00485 rd_vals[RV_STATUS_START].n = "Start";
00486 rd_vals[RV_STATUS_STOP].n = "Stop";
00487 rd_vals[RV_STATUS_ALIVE].n = "Alive";
00488 rd_vals[RV_STATUS_FAILED].n = "Failed";
00489 rd_vals[RV_SIP_SESSION].n = "Sip-Session";
00490
00491
00492 n += extra2attrs( rad_extra, rd_attrs, n);
00493
00494 n += extra2attrs( leg_info, rd_attrs, n);
00495
00496
00497 if ((rh = rc_read_config(rad_cfg)) == NULL) {
00498 LM_ERR("failed to open radius config file: %s\n", rad_cfg );
00499 return -1;
00500 }
00501
00502 if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))!=0) {
00503 LM_ERR("failed to read radius dictionary\n");
00504 return -1;
00505 }
00506
00507 INIT_AV(rh, rd_attrs, n, rd_vals, RV_STATIC_MAX, "acc", -1, -1);
00508
00509 if (srv_type != -1)
00510 rd_vals[RV_SIP_SESSION].v = srv_type;
00511
00512 return 0;
00513 }
00514
00515
00516 static inline UINT4 rad_status( struct sip_msg *req, int code )
00517 {
00518 str tag;
00519 unsigned int in_dialog_req = 0;
00520
00521 tag = get_to(req)->tag_value;
00522 if(tag.s!=0 && tag.len!=0)
00523 in_dialog_req = 1;
00524
00525 if (req->REQ_METHOD==METHOD_INVITE && in_dialog_req == 0
00526 && code>=200 && code<300)
00527 return rd_vals[RV_STATUS_START].v;
00528 if ((req->REQ_METHOD==METHOD_BYE || req->REQ_METHOD==METHOD_CANCEL))
00529 return rd_vals[RV_STATUS_STOP].v;
00530 if (in_dialog_req != 0)
00531 return rd_vals[RV_STATUS_ALIVE].v;
00532 return rd_vals[RV_STATUS_FAILED].v;
00533 }
00534
00535 #define ADD_RAD_AVPAIR(_attr,_val,_len) \
00536 do { \
00537 if (!rc_avpair_add(rh, &send, rd_attrs[_attr].v, _val, _len, 0)) { \
00538 LM_ERR("failed to add %s, %d\n", rd_attrs[_attr].n, _attr); \
00539 goto error; \
00540 } \
00541 }while(0)
00542
00543 int acc_rad_request( struct sip_msg *req )
00544 {
00545 int attr_cnt;
00546 VALUE_PAIR *send;
00547 UINT4 av_type;
00548 int offset;
00549 int i;
00550
00551 send=NULL;
00552
00553 attr_cnt = core2strar( req, val_arr, int_arr, type_arr );
00554
00555 attr_cnt -= 2;
00556
00557 av_type = rad_status( req, acc_env.code);
00558 ADD_RAD_AVPAIR( RA_ACCT_STATUS_TYPE, &av_type, -1);
00559
00560 av_type = rd_vals[RV_SIP_SESSION].v;
00561 ADD_RAD_AVPAIR( RA_SERVICE_TYPE, &av_type, -1);
00562
00563 av_type = (UINT4)acc_env.code;
00564 ADD_RAD_AVPAIR( RA_SIP_RESPONSE_CODE, &av_type, -1);
00565
00566 av_type = req->REQ_METHOD;
00567 ADD_RAD_AVPAIR( RA_SIP_METHOD, &av_type, -1);
00568
00569
00570 av_type = (UINT4)acc_env.ts;
00571 ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1);
00572
00573
00574 attr_cnt += extra2strar(rad_extra, req, val_arr+attr_cnt,
00575 int_arr+attr_cnt, type_arr+attr_cnt);
00576
00577
00578
00579 offset = RA_STATIC_MAX-1;
00580 for( i=1; i<attr_cnt; i++) {
00581 switch (type_arr[i]) {
00582 case TYPE_STR:
00583 ADD_RAD_AVPAIR(offset+i, val_arr[i].s, val_arr[i].len);
00584 break;
00585 case TYPE_INT:
00586 ADD_RAD_AVPAIR(offset+i, &(int_arr[i]), -1);
00587 break;
00588 default:
00589 break;
00590 }
00591 }
00592
00593
00594 if ( leg_info ) {
00595 offset += attr_cnt;
00596 attr_cnt = legs2strar(leg_info,req,val_arr,int_arr,type_arr,1);
00597 do {
00598 for (i=0; i<attr_cnt; i++)
00599 ADD_RAD_AVPAIR( offset+i, val_arr[i].s, val_arr[i].len );
00600 }while ( (attr_cnt=legs2strar(leg_info,req,val_arr,int_arr,
00601 type_arr, 0))!=0 );
00602 }
00603
00604 if (rc_acct(rh, SIP_PORT, send)!=OK_RC) {
00605 LM_ERR("radius-ing failed\n");
00606 goto error;
00607 }
00608 rc_avpair_free(send);
00609 return 1;
00610
00611 error:
00612 rc_avpair_free(send);
00613 return -1;
00614 }
00615
00616 #endif
00617
00618
00619
00620
00621
00622 #ifdef DIAM_ACC
00623
00624 #define AA_REQUEST 265
00625 #define AA_ANSWER 265
00626
00627 #define ACCOUNTING_REQUEST 271
00628 #define ACCOUNTING_ANSWER 271
00629
00630 static int diam_attrs[ACC_CORE_LEN+MAX_ACC_EXTRA+MAX_ACC_LEG];
00631
00632 int acc_diam_init()
00633 {
00634 int n;
00635 int m;
00636
00637 n = 0;
00638
00639 diam_attrs[n++] = AVP_SIP_METHOD;
00640 diam_attrs[n++] = AVP_SIP_FROM_TAG;
00641 diam_attrs[n++] = AVP_SIP_TO_TAG;
00642 diam_attrs[n++] = AVP_SIP_CALLID;
00643 diam_attrs[n++] = AVP_SIP_STATUS;
00644
00645 m = extra2int( dia_extra, diam_attrs+n);
00646 if (m<0) {
00647 LM_ERR("extra names for DIAMETER must be integer AVP codes\n");
00648 return -1;
00649 }
00650 n += m;
00651
00652 m = extra2int( leg_info, diam_attrs+n);
00653 if (m<0) {
00654 LM_ERR("leg info names for DIAMTER must be integer AVP codes\n");
00655 return -1;
00656 }
00657 n += m;
00658
00659 return 0;
00660 }
00661
00662
00663 inline unsigned long diam_status(struct sip_msg *rq, int code)
00664 {
00665 if ((rq->REQ_METHOD==METHOD_INVITE || rq->REQ_METHOD==METHOD_ACK)
00666 && code>=200 && code<300)
00667 return AAA_ACCT_START;
00668
00669 if ((rq->REQ_METHOD==METHOD_BYE || rq->REQ_METHOD==METHOD_CANCEL))
00670 return AAA_ACCT_STOP;
00671
00672 if (code>=200 && code <=300)
00673 return AAA_ACCT_EVENT;
00674
00675 return -1;
00676 }
00677
00678
00679 int acc_diam_request( struct sip_msg *req )
00680 {
00681 int attr_cnt;
00682 int cnt;
00683 AAAMessage *send = NULL;
00684 AAA_AVP *avp;
00685 struct sip_uri puri;
00686 str *uri;
00687 int ret;
00688 int i;
00689 int status;
00690 char tmp[2];
00691 unsigned int mid;
00692
00693 attr_cnt = core2strar( req, val_arr, int_arr, type_arr );
00694
00695 attr_cnt--;
00696
00697 if ( (send=AAAInMessage(ACCOUNTING_REQUEST, AAA_APP_NASREQ))==NULL) {
00698 LM_ERR("failed to create new AAA request\n");
00699 return -1;
00700 }
00701
00702
00703 if( (status = diam_status(req, acc_env.code))<0) {
00704 LM_ERR("status unknown\n");
00705 goto error;
00706 }
00707 tmp[0] = status+'0';
00708 tmp[1] = 0;
00709 if( (avp=AAACreateAVP(AVP_Accounting_Record_Type, 0, 0, tmp,
00710 1, AVP_DUPLICATE_DATA)) == 0) {
00711 LM_ERR("failed to create AVP:no more free memory!\n");
00712 goto error;
00713 }
00714 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00715 LM_ERR("avp not added \n");
00716 AAAFreeAVP(&avp);
00717 goto error;
00718 }
00719
00720 mid = req->id;
00721 if( (avp=AAACreateAVP(AVP_SIP_MSGID, 0, 0, (char*)(&mid),
00722 sizeof(mid), AVP_DUPLICATE_DATA)) == 0) {
00723 LM_ERR("failed to create AVP:no more free memory!\n");
00724 goto error;
00725 }
00726 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00727 LM_ERR("avp not added \n");
00728 AAAFreeAVP(&avp);
00729 goto error;
00730 }
00731
00732
00733 if( (avp=AAACreateAVP(AVP_Service_Type, 0, 0, SIP_ACCOUNTING,
00734 SERVICE_LEN, AVP_DUPLICATE_DATA)) == 0) {
00735 LM_ERR("failed to create AVP:no more free memory!\n");
00736 goto error;
00737 }
00738 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00739 LM_ERR("avp not added \n");
00740 AAAFreeAVP(&avp);
00741 goto error;
00742 }
00743
00744
00745 attr_cnt += extra2strar( dia_extra, req, val_arr, int_arr, type_arr);
00746
00747
00748 for(i=0; i<attr_cnt; i++) {
00749 if((avp=AAACreateAVP(diam_attrs[i], 0,0, val_arr[i].s, val_arr[i].len,
00750 AVP_DUPLICATE_DATA)) == 0) {
00751 LM_ERR("failed to create AVP: no more free memory!\n");
00752 goto error;
00753 }
00754 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00755 LM_ERR("avp not added \n");
00756 AAAFreeAVP(&avp);
00757 goto error;
00758 }
00759 }
00760
00761
00762 if ( leg_info ) {
00763 cnt = legs2strar(leg_info,req,val_arr,int_arr,type_arr,1);
00764 do {
00765 for (i=0; i<cnt; i++) {
00766 if((avp=AAACreateAVP(diam_attrs[attr_cnt+i], 0, 0,
00767 val_arr[i].s, val_arr[i].len, AVP_DUPLICATE_DATA)) == 0) {
00768 LM_ERR("failed to create AVP: no more free memory!\n");
00769 goto error;
00770 }
00771 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00772 LM_ERR("avp not added \n");
00773 AAAFreeAVP(&avp);
00774 goto error;
00775 }
00776 }
00777 } while ( (cnt=legs2strar(leg_info,req,val_arr,int_arr,
00778 type_arr,0))!=0 );
00779 }
00780
00781 if (get_uri(req, &uri) < 0) {
00782 LM_ERR("failed to get uri, From/To URI not found\n");
00783 goto error;
00784 }
00785
00786 if (parse_uri(uri->s, uri->len, &puri) < 0) {
00787 LM_ERR("failed to parse From/To URI\n");
00788 goto error;
00789 }
00790
00791
00792 if( (avp=AAACreateAVP(AVP_Destination_Realm, 0, 0, puri.host.s,
00793 puri.host.len, AVP_DUPLICATE_DATA)) == 0) {
00794 LM_ERR("failed to create AVP:no more free memory!\n");
00795 goto error;
00796 }
00797
00798 if( AAAAddAVPToMessage(send, avp, 0)!= AAA_ERR_SUCCESS) {
00799 LM_ERR("avp not added \n");
00800 AAAFreeAVP(&avp);
00801 goto error;
00802 }
00803
00804
00805 if(AAABuildMsgBuffer(send) != AAA_ERR_SUCCESS) {
00806 LM_ERR("message buffer not created\n");
00807 goto error;
00808 }
00809
00810 if(sockfd==AAA_NO_CONNECTION) {
00811 sockfd = init_mytcp(diameter_client_host, diameter_client_port);
00812 if(sockfd==AAA_NO_CONNECTION) {
00813 LM_ERR("failed to reconnect to Diameter client\n");
00814 goto error;
00815 }
00816 }
00817
00818
00819 ret = tcp_send_recv(sockfd, send->buf.s, send->buf.len, rb, req->id);
00820 if(ret == AAA_CONN_CLOSED) {
00821 LM_NOTICE("connection to Diameter client closed.It will be "
00822 "reopened by the next request\n");
00823 close(sockfd);
00824 sockfd = AAA_NO_CONNECTION;
00825 goto error;
00826 }
00827
00828 if(ret != ACC_SUCCESS) {
00829
00830 LM_ERR("message sending to the DIAMETER backend authorization "
00831 "server failed\n");
00832 goto error;
00833 }
00834
00835 AAAFreeMessage(&send);
00836 return 1;
00837
00838 error:
00839 AAAFreeMessage(&send);
00840 return -1;
00841 }
00842
00843 #endif
00844
00848 int acc_run_engines(struct sip_msg *msg, int type, int *reset)
00849 {
00850 acc_info_t inf;
00851 acc_engine_t *e;
00852
00853 e = acc_api_get_engines();
00854
00855 if(e==NULL)
00856 return 0;
00857
00858 memset(&inf, 0, sizeof(acc_info_t));
00859 inf.env = &acc_env;
00860 inf.varr = val_arr;
00861 inf.iarr = int_arr;
00862 inf.tarr = type_arr;
00863 inf.leg_info = leg_info;
00864 while(e) {
00865 if(e->flags & 1) {
00866 if((type==0) && (msg->flags&(e->acc_flag))) {
00867 LM_DBG("acc event for engine: %s\n", e->name);
00868 e->acc_req(msg, &inf);
00869 if(reset) *reset |= e->acc_flag;
00870 }
00871 if((type==1) && (msg->flags&(e->missed_flag))) {
00872 LM_DBG("missed event for engine: %s\n", e->name);
00873 e->acc_req(msg, &inf);
00874 if(reset) *reset |= e->missed_flag;
00875 }
00876 }
00877 e = e->next;
00878 }
00879 return 0;
00880 }
00881
00885 void acc_api_set_arrays(acc_info_t *inf)
00886 {
00887 inf->varr = val_arr;
00888 inf->iarr = int_arr;
00889 inf->tarr = type_arr;
00890 inf->leg_info = leg_info;
00891 }
00892