/** * Timer callback for checking the transaction status. * @param now - time of call * @param ptr - generic pointer, passed to the transactional callbacks */ int cdp_trans_timer(time_t now, void* ptr) { cdp_trans_t *x,*n; LOG(L_MEM,"DBG:trans_timer(): taking care of diameter transactions...\n"); lock_get(trans_list->lock); x = trans_list->head; while(x) { if (now>x->expires){ x->ans = 0; if (x->cb){ (x->cb)(1,*(x->ptr),0); } n = x->next; if (x->prev) x->prev->next = x->next; else trans_list->head = x->next; if (x->next) x->next->prev = x->prev; else trans_list->tail = x->prev; if (x->auto_drop) cdp_free_trans(x); x = n; } else x = x->next; } lock_release(trans_list->lock); return 1; }
/** * Timer callback for checking the transaction status. * @param now - time of call * @param ptr - generic pointer, passed to the transactional callbacks */ int cdp_trans_timer(time_t now, void* ptr) { cdp_trans_t *x,*n; lock_get(trans_list->lock); x = trans_list->head; while(x) { if (now>x->expires) { counter_inc(cdp_cnts_h.timeout); //Transaction has timed out waiting for response x->ans = 0; if (x->cb) { (x->cb)(1,*(x->ptr),0, (now - x->expires)); } n = x->next; if (x->prev) x->prev->next = x->next; else trans_list->head = x->next; if (x->next) x->next->prev = x->prev; else trans_list->tail = x->prev; if (x->auto_drop) cdp_free_trans(x); x = n; } else x = x->next; } lock_release(trans_list->lock); return 1; }
/** * Remove from the list and deallocate a transaction. * @param msg - the message that relates to that particular transaction */ inline void del_trans(AAAMessage *msg) { cdp_trans_t *x; lock_get(trans_list->lock); x = trans_list->head; while(x&& x->endtoendid!=msg->endtoendId && x->hopbyhopid!=msg->hopbyhopId) x = x->next; if (x){ if (x->prev) x->prev->next = x->next; else trans_list->head = x->next; if (x->next) x->next->prev = x->prev; else trans_list->tail = x->prev; cdp_free_trans(x); } lock_release(trans_list->lock); }
/** * Send a AAAMessage synchronously. * This blocks until a response is received or a transactional time-out happens. * @param message - the request to be sent * @param peer_id - FQDN of the peer to send * @returns 1 on success, 0 on failure * \todo remove peer_id and add Realm routing * \todo replace the busy-waiting lock in here with one that does not consume CPU */ AAAMessage* AAASendRecvMessageToPeer(AAAMessage *message, str *peer_id) { peer *p; gen_sem_t *sem; cdp_trans_t *t; AAAMessage *ans; p = get_peer_by_fqdn(peer_id); if (!p) { LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): Peer unknown %.*s\n",peer_id->len,peer_id->s); goto error; } if (p->state!=I_Open && p->state!=R_Open){ LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): Peer not connected to %.*s\n",peer_id->len,peer_id->s); goto error; } if (is_req(message)){ sem_new(sem,0); t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0); // if (!peer_send_msg(p,message)) { if (!sm_process(p,Send_Message,message,0,0)){ sem_free(sem); goto error; } /* block until callback is executed */ while(sem_get(sem)<0){ if (shutdownx&&(*shutdownx)) goto error; LOG(L_WARN,"WARN:AAASendRecvMessageToPeer(): interrupted by signal or something > %s\n",strerror(errno)); } sem_free(sem); ans = t->ans; cdp_free_trans(t); return ans; } else { LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): can't add wait for answer to answer.\n"); goto error; } error: out_of_memory: AAAFreeMessage(&message); return 0; }
int cdp_trans_destroy() { cdp_trans_t *t=0; if (trans_list){ lock_get(trans_list->lock); while(trans_list->head){ t = trans_list->head; trans_list->head = t->next; cdp_free_trans(t); } lock_destroy(trans_list->lock); lock_dealloc((void*)trans_list->lock); shm_free(trans_list); trans_list = 0; } return 1; }