Navigation


source: freeDiameter/freeDiameter/p_sr.c @ 258:5df55136361b

Last change on this file since 258:5df55136361b was 258:5df55136361b, checked in by Sebastien Decugis <sdecugis@nict.go.jp>, 3 years ago

Updated copyright information

File size: 6.0 KB
Line 
1/*********************************************************************************************************
2* Software License Agreement (BSD License)                                                               *
3* Author: Sebastien Decugis <sdecugis@nict.go.jp>                                                        *
4*                                                                                                        *
5* Copyright (c) 2010, WIDE Project and NICT                                                              *
6* All rights reserved.                                                                                   *
7*                                                                                                        *
8* Redistribution and use of this software in source and binary forms, with or without modification, are  *
9* permitted provided that the following conditions are met:                                              *
10*                                                                                                        *
11* * Redistributions of source code must retain the above                                                 *
12*   copyright notice, this list of conditions and the                                                    *
13*   following disclaimer.                                                                                *
14*                                                                                                        *
15* * Redistributions in binary form must reproduce the above                                              *
16*   copyright notice, this list of conditions and the                                                    *
17*   following disclaimer in the documentation and/or other                                               *
18*   materials provided with the distribution.                                                            *
19*                                                                                                        *
20* * Neither the name of the WIDE Project or NICT nor the                                                 *
21*   names of its contributors may be used to endorse or                                                  *
22*   promote products derived from this software without                                                  *
23*   specific prior written permission of WIDE Project and                                                *
24*   NICT.                                                                                                *
25*                                                                                                        *
26* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
27* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
28* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
29* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT     *
30* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS    *
31* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
32* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
33* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                                             *
34*********************************************************************************************************/
35
36#include "fD.h"
37
38#ifndef SR_DEBUG_LVL
39#define SR_DEBUG_LVL ANNOYING
40#endif /* SR_DEBUG_LVL */
41
42/* Structure to store a sent request */
43struct sentreq {
44        struct fd_list  chain;  /* the "o" field points directly to the hop-by-hop of the request (uint32_t *)  */
45        struct msg      *req;   /* A request that was sent and not yet answered. */
46        uint32_t        prevhbh;/* The value to set in the hbh header when the message is retrieved */
47};
48
49/* Find an element in the list, or the following one */
50static struct fd_list * find_or_next(struct fd_list * srlist, uint32_t hbh, int * match)
51{
52        struct fd_list * li;
53        *match = 0;
54        for (li = srlist->next; li != srlist; li = li->next) {
55                uint32_t * nexthbh = li->o;
56                if (*nexthbh < hbh)
57                        continue;
58                if (*nexthbh == hbh)
59                        *match = 1;
60                break;
61        }
62        return li;
63}
64
65static void srl_dump(const char * text, struct fd_list * srlist)
66{
67        struct fd_list * li;
68        if (!TRACE_BOOL(SR_DEBUG_LVL))
69                return;
70        fd_log_debug("%sSentReq list @%p:\n", text, srlist);
71        for (li = srlist->next; li != srlist; li = li->next) {
72                struct sentreq * sr = (struct sentreq *)li;
73                uint32_t * nexthbh = li->o;
74                fd_log_debug(" - Next req (%x):\n", *nexthbh);
75                fd_msg_dump_one(SR_DEBUG_LVL + 1, sr->req);
76        }
77}
78
79/* Store a new sent request */
80int fd_p_sr_store(struct sr_list * srlist, struct msg **req, uint32_t *hbhloc, uint32_t hbh_restore)
81{
82        struct sentreq * sr;
83        struct fd_list * next;
84        int match;
85       
86        TRACE_ENTRY("%p %p %p %x", srlist, req, hbhloc, hbh_restore);
87        CHECK_PARAMS(srlist && req && *req && hbhloc);
88       
89        CHECK_MALLOC( sr = malloc(sizeof(struct sentreq)) );
90        memset(sr, 0, sizeof(struct sentreq));
91        fd_list_init(&sr->chain, hbhloc);
92        sr->req = *req;
93        sr->prevhbh = hbh_restore;
94       
95        /* Search the place in the list */
96        CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) );
97        next = find_or_next(&srlist->srs, *hbhloc, &match);
98        if (match) {
99                TRACE_DEBUG(INFO, "A request with the same hop-by-hop Id was already sent: error");
100                free(sr);
101                CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* ignore */ );
102                return EINVAL;
103        }
104       
105        /* Save in the list */
106        *req = NULL;
107        fd_list_insert_before(next, &sr->chain);
108        srl_dump("Saved new request, ", &srlist->srs);
109        CHECK_POSIX( pthread_mutex_unlock(&srlist->mtx) );
110        return 0;
111}
112
113/* Fetch a request by hbh */
114int fd_p_sr_fetch(struct sr_list * srlist, uint32_t hbh, struct msg **req)
115{
116        struct sentreq * sr;
117        int match;
118       
119        TRACE_ENTRY("%p %x %p", srlist, hbh, req);
120        CHECK_PARAMS(srlist && req);
121       
122        /* Search the request in the list */
123        CHECK_POSIX( pthread_mutex_lock(&srlist->mtx) );
124        srl_dump("Fetching a request, ", &srlist->srs);
125        sr = (struct sentreq *)find_or_next(&srlist->srs, hbh, &match);
126        if (!match) {
127                TRACE_DEBUG(INFO, "There is no saved request with this hop-by-hop id (%x)", hbh);
128                *req = NULL;
129        } else {
130                /* Restore hop-by-hop id */
131                *((uint32_t *)sr->chain.o) = sr->prevhbh;
132                /* Unlink */
133                fd_list_unlink(&sr->chain);
134                *req = sr->req;
135                free(sr);
136        }
137        CHECK_POSIX( pthread_mutex_unlock(&srlist->mtx) );
138
139        /* Done */
140        return 0;
141}
142
143/* Failover requests (free or requeue routables) */
144void fd_p_sr_failover(struct sr_list * srlist)
145{
146        CHECK_POSIX_DO( pthread_mutex_lock(&srlist->mtx), /* continue anyway */ );
147        while (!FD_IS_LIST_EMPTY(&srlist->srs)) {
148                struct sentreq * sr = (struct sentreq *)(srlist->srs.next);
149                fd_list_unlink(&sr->chain);
150                if (fd_msg_is_routable(sr->req)) {
151                        struct msg_hdr * hdr = NULL;
152                       
153                        /* Set the 'T' flag */
154                        CHECK_FCT_DO(fd_msg_hdr(sr->req, &hdr), /* continue */);
155                        if (hdr)
156                                hdr->msg_flags |= CMD_FLAG_RETRANSMIT;
157                       
158                        /* Requeue for sending to another peer */
159                        CHECK_FCT_DO(fd_fifo_post(fd_g_outgoing, &sr->req),
160                                        CHECK_FCT_DO(fd_msg_free(sr->req), /* What can we do more? */));
161                } else {
162                        /* Just free the request... */
163                        CHECK_FCT_DO(fd_msg_free(sr->req), /* Ignore */);
164                }
165                free(sr);
166        }
167        CHECK_POSIX_DO( pthread_mutex_unlock(&srlist->mtx), /* continue anyway */ );
168}
169
Note: See TracBrowser for help on using the repository browser.