Navigation


Changeset 1103:d8591b1c56cd in freeDiameter for libfdcore/hooks.c


Ignore:
Timestamp:
May 10, 2013, 7:48:57 PM (11 years ago)
Author:
Sebastien Decugis <sdecugis@freediameter.net>
Branch:
default
Phase:
public
Message:

Implemented a few hooks

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdcore/hooks.c

    r1098 r1103  
    186186        in_msg = fd_msg_pmdl_get(msg);
    187187        ASSERT(in_msg && (in_msg->sentinel.o == NULL)); /* error / already initialized ??? */
    188         fd_list_init(&in_msg->sentinel, pmdl_free);
    189         CHECK_POSIX_DO( pthread_mutex_init(&in_msg->lock, NULL), );
     188        in_msg->sentinel.o = pmdl_free;
    190189        /* Now move all items from the pmdl pointer into the initialized list */
    191190        CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), );
     
    201200        struct fd_hook_permsgdata * ret = NULL;
    202201        struct fd_list * li;
     202       
    203203        CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), );
     204       
     205        if (pmdl->sentinel.o == NULL) {
     206                pmdl->sentinel.o = pmdl_free;
     207        }
    204208       
    205209        /* Search in the list for an item with the same handle. The list is ordered by this handle */
     
    231235}
    232236
     237struct fd_hook_permsgdata * fd_hook_get_request_pmd(struct fd_hook_data_hdl *data_hdl, struct msg * answer)
     238{
     239        struct msg * qry;
     240        struct fd_msg_pmdl *pmdl;
     241        struct fd_hook_permsgdata * ret = NULL;
     242        struct fd_list * li;
     243       
     244        CHECK_FCT_DO( fd_msg_answ_getq(answer, &qry), return NULL );
     245        if (!qry)
     246                return NULL;
     247       
     248        pmdl = fd_msg_pmdl_get(qry);
     249        if (!pmdl)
     250                return NULL;
     251       
     252        CHECK_POSIX_DO( pthread_mutex_lock(&pmdl->lock), );
     253        /* Search in the list for an item with the same handle. The list is ordered by this handle */
     254        for (li=pmdl->sentinel.next; li != &pmdl->sentinel; li = li->next) {
     255                struct pmd_list_item * pli = (struct pmd_list_item *) li;
     256                if (pli->hdl == data_hdl)
     257                        ret = &pli->pmd;
     258                if (pli->hdl >= data_hdl)
     259                        break;
     260        }
     261        CHECK_POSIX_DO( pthread_mutex_unlock(&pmdl->lock), );
     262        return ret;
     263}
    233264
    234265/* The function that does the work of calling the extension's callbacks and also managing the permessagedata structures */
     
    237268        struct fd_list * li;
    238269        ASSERT(type <= HOOK_PEER_LAST);
     270        int call_default = 0;
    239271       
    240272        /* lock the list of hooks for this type */
    241273        CHECK_POSIX_DO( pthread_rwlock_rdlock(&HS_array[type].rwlock), );
    242274       
    243         /* for each registered hook */
    244         for (li = HS_array[type].sentinel.next; li != &HS_array[type].sentinel; li = li->next) {
    245                 struct fd_hook_hdl * h = (struct fd_hook_hdl *)li->o;
    246                 struct fd_hook_permsgdata * pmd = NULL;
    247                
    248                 /* do we need to handle pmd ? */
    249                 if (h->data_hdl && pmdl) {
    250                         pmd = get_or_create_pmd(pmdl, h);
    251                 }
    252                
    253                 /* Now, call this callback */
    254                 (*h->fd_hook_cb)(type, msg, &peer->p_hdr, other, pmd, h->regdata);
     275        if (FD_IS_LIST_EMPTY(&HS_array[type].sentinel)) {
     276                call_default = 1;
     277        } else {
     278                /* for each registered hook */
     279                for (li = HS_array[type].sentinel.next; li != &HS_array[type].sentinel; li = li->next) {
     280                        struct fd_hook_hdl * h = (struct fd_hook_hdl *)li->o;
     281                        struct fd_hook_permsgdata * pmd = NULL;
     282
     283                        /* do we need to handle pmd ? */
     284                        if (h->data_hdl && pmdl) {
     285                                pmd = get_or_create_pmd(pmdl, h);
     286                        }
     287
     288                        /* Now, call this callback */
     289                        (*h->fd_hook_cb)(type, msg, &peer->p_hdr, other, pmd, h->regdata);
     290                }
    255291        }
    256292       
    257293        /* done */
    258294        CHECK_POSIX_DO( pthread_rwlock_unlock(&HS_array[type].rwlock), );
    259 }
     295       
     296        if (call_default) {
     297                char * buf = NULL;
     298                size_t len = 0;
     299       
     300                /* There was no registered handler, default behavior for this hook */
     301                switch (type) {
     302                        case HOOK_DATA_RECEIVED: {
     303                                struct fd_cnx_rcvdata *rcv_data = other;
     304                                LOG_A("RCV: %zd bytes", rcv_data->length);
     305                                break;
     306                        }
     307                       
     308                        case HOOK_MESSAGE_RECEIVED: {
     309                                CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break);
     310                                LOG_D("RCV from '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf);
     311                                break;
     312                        }
     313                       
     314                        case HOOK_MESSAGE_LOCAL: {
     315                                CHECK_MALLOC_DO(fd_msg_dump_full(&buf, &len, NULL, msg, NULL, 0, 1), break);
     316                                LOG_A("Handled to framework for sending: %s", buf);
     317                                break;
     318                        }
     319                       
     320                        case HOOK_MESSAGE_SENT: {
     321                                CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break);
     322                                LOG_D("SENT to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf);
     323                                break;
     324                        }
     325                       
     326                        case HOOK_MESSAGE_FAILOVER: {
     327                                CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break);
     328                                LOG_D("Failing over message sent to '%s': %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf);
     329                                break;
     330                        }
     331                       
     332                        case HOOK_MESSAGE_PARSING_ERROR: {
     333                                if (msg) {
     334                                        DiamId_t id = NULL;
     335                                        size_t idlen;
     336                                        if (!fd_msg_source_get( msg, &id, &idlen ))
     337                                                id = (DiamId_t)"<error getting source>";
     338                                       
     339                                        if (!id)
     340                                                id = (DiamId_t)"<local>";
     341                                       
     342                                        CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break);
     343                                       
     344                                        LOG_E("Parsing error: '%s' for the following message received from '%s':\n%s", (char *)other, (char *)id, buf);
     345                                } else {
     346                                        struct fd_cnx_rcvdata *rcv_data = other;
     347                                        CHECK_MALLOC_DO(fd_dump_extend_hexdump(&buf, &len, NULL, rcv_data->buffer, rcv_data->length, 0, 0), break);
     348                                        LOG_E("Parsing error: cannot parse %zdB buffer from '%s': %s",  rcv_data->length, peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf);
     349                                }
     350                                break;
     351                        }
     352                       
     353                        case HOOK_MESSAGE_ROUTING_ERROR: {
     354                                DiamId_t id = NULL;
     355                                size_t idlen;
     356                                if (!fd_msg_source_get( msg, &id, &idlen ))
     357                                        id = (DiamId_t)"<error getting source>";
     358
     359                                if (!id)
     360                                        id = (DiamId_t)"<local>";
     361
     362                                CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break);
     363
     364                                LOG_E("Routing error: '%s' for the following message:\n%s", (char *)other, buf);
     365                                break;
     366                        }
     367                       
     368                        case HOOK_MESSAGE_ROUTING_FORWARD: {
     369                                CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break);
     370                                LOG_D("FORWARDING: %s", buf);
     371                                break;
     372                        }
     373                       
     374                        case HOOK_MESSAGE_ROUTING_LOCAL: {
     375                                CHECK_MALLOC_DO(fd_msg_dump_summary(&buf, &len, NULL, msg, NULL, 0, 1), break);
     376                                LOG_D("DISPATCHING: %s", buf);
     377                                break;
     378                        }
     379                       
     380                        case HOOK_MESSAGE_DROPPED: {
     381                                CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break);
     382                                LOG_E("Message discarded ('%s'):\n%s", (char *)other, buf);
     383                                break;
     384                        }
     385                       
     386                        case HOOK_PEER_CONNECT_FAILED: {
     387                                if (msg) {
     388                                        size_t offset = 0;
     389                                        CHECK_MALLOC_DO(fd_dump_extend(&buf, &len, &offset, " CER/CEA dump:\n"), break);
     390                                        CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, &offset, msg, NULL, 0, 1), break);
     391                                        LOG_N("Connection to '%s' failed: %s%s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", (char *)other, buf);
     392                                } else {
     393                                        LOG_D("Connection to '%s' failed: %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", (char *)other);
     394                                }
     395                                break;
     396                        }
     397                       
     398                        case HOOK_PEER_CONNECT_SUCCESS: {
     399                                CHECK_MALLOC_DO(fd_msg_dump_treeview(&buf, &len, NULL, msg, NULL, 0, 1), break);
     400                                LOG_N("Connected to '%s', remote capabilities: %s", peer ? peer->p_hdr.info.pi_diamid : "<unknown>", buf);
     401                                break;
     402                        }
     403                       
     404                }
     405               
     406                free(buf);
     407        }
     408}
Note: See TracChangeset for help on using the changeset viewer.