annotate extensions/rt_rewrite/rt_rewrite.c @ 1547:44bb63ba9c2c

rt_rewrite: allocate object later to reduce cleanups
author Thomas Klausner <tk@giga.or.at>
date Mon, 15 Jun 2020 20:33:35 +0200
parents c8057892e56b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
1 /*********************************************************************************************************
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
2 * Software License Agreement (BSD License) *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
3 * Author: Thomas Klausner <tk@giga.or.at> *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
4 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
5 * Copyright (c) 2018, Thomas Klausner *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
6 * All rights reserved. *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
7 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
8 * Written under contract by Effortel Technologies SA, http://effortel.com/ *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
9 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
10 * Redistribution and use of this software in source and binary forms, with or without modification, are *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
11 * permitted provided that the following conditions are met: *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
12 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
13 * * Redistributions of source code must retain the above *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
14 * copyright notice, this list of conditions and the *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
15 * following disclaimer. *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
16 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
17 * * Redistributions in binary form must reproduce the above *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
18 * copyright notice, this list of conditions and the *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
19 * following disclaimer in the documentation and/or other *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
20 * materials provided with the distribution. *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
21 * *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
28 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
30 *********************************************************************************************************/
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
31
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
32 #include <freeDiameter/extension.h>
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
33 #include "rt_rewrite.h"
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
34
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
35 #include <pthread.h>
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
36 #include <signal.h>
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
37
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
38 /*
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
39 * Replace AVPs: put their values into other AVPs
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
40 * Remove AVPs: drop them from a message
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
41 */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
42
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
43 /* handler */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
44 static struct fd_rt_fwd_hdl * rt_rewrite_handle = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
45
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
46 static char *config_file;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
47
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
48 struct avp_match *avp_match_start = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
49
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
50 static pthread_rwlock_t rt_rewrite_lock;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
51
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
52 #define MODULE_NAME "rt_rewrite"
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
53
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
54 struct store {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
55 struct avp *avp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
56 struct avp_target *target;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
57 struct store *next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
58 };
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
59
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
60 static struct store *store_new(void) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
61 struct store *ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
62
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
63 if ((ret=malloc(sizeof(*ret))) == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
64 fd_log_error("%s: malloc failure", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
65 return NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
66 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
67 ret->avp = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
68 ret->target = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
69 ret->next = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
70
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
71 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
72 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
73
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
74 static void store_free(struct store *store)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
75 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
76 while (store) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
77 struct store *next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
78 if (store->avp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
79 fd_msg_free((msg_or_avp *)store->avp);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
80 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
81 store->target = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
82 next = store->next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
83 free(store);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
84 store = next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
85 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
86 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
87 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
88
1424
c8057892e56b adapt extensions to fd_msg_search_avp(struct avp)
Luke Mewburn <luke@mewburn.net>
parents: 1388
diff changeset
89 /* TODO: convert to fd_msg_search_avp ? */
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
90 static int fd_avp_search_avp(msg_or_avp *where, struct dict_object *what, struct avp **avp)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
91 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
92 struct avp *nextavp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
93 struct dict_avp_data dictdata;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
94 enum dict_object_type dicttype;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
95
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
96 CHECK_PARAMS((fd_dict_gettype(what, &dicttype) == 0) && (dicttype == DICT_AVP));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
97 CHECK_FCT(fd_dict_getval(what, &dictdata));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
98
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
99 /* Loop on all top AVPs */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
100 CHECK_FCT(fd_msg_browse(where, MSG_BRW_FIRST_CHILD, (void *)&nextavp, NULL));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
101 while (nextavp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
102 struct avp_hdr *header = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
103 struct dict_object *model = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
104 if (fd_msg_avp_hdr(nextavp, &header) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
105 fd_log_notice("%s: unable to get header for AVP", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
106 return -1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
107 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
108 if (fd_msg_model(nextavp, &model) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
109 fd_log_notice("%s: unable to get model for AVP (%d, vendor %d)", MODULE_NAME, header->avp_code, header->avp_vendor);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
110 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
111 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
112 if (model == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
113 fd_log_notice("%s: unknown AVP (%d, vendor %d) (not in dictionary), skipping", MODULE_NAME, header->avp_code, header->avp_vendor);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
114 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
115 if ((header->avp_code == dictdata.avp_code) && (header->avp_vendor == dictdata.avp_vendor)) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
116 break;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
117 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
118 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
119
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
120 /* Otherwise move to next AVP in the message */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
121 CHECK_FCT(fd_msg_browse(nextavp, MSG_BRW_NEXT, (void *)&nextavp, NULL) );
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
122 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
123
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
124 if (avp)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
125 *avp = nextavp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
126
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
127 if (*avp || nextavp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
128 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
129 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
130 return ENOENT;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
131 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
132 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
133
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
134
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
135
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
136 static msg_or_avp *find_container(msg_or_avp *msg, struct avp_target *target)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
137 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
138 msg_or_avp *location = msg;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
139 while (target->child) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
140 struct dict_object *avp_do;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
141 msg_or_avp *new_location = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
142 int ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
143
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
144 fd_log_debug("%s: looking for '%s'", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
145 if ((ret=fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, target->name, &avp_do, ENOENT)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
146 fd_log_error("%s: target AVP '%s' not in dictionary: %s", MODULE_NAME, target->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
147 return NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
148 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
149 if ((ret=fd_avp_search_avp(location, avp_do, (struct avp **)&new_location)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
150 fd_log_debug("%s: did not find '%s', adding it", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
151 struct avp *avp = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
152 if ((ret = fd_msg_avp_new(avp_do, 0, &avp)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
153 fd_log_notice("%s: unable to create new '%s' AVP", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
154 return NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
155 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
156 if ((ret=fd_msg_avp_add(location, MSG_BRW_LAST_CHILD, avp)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
157 fd_log_error("%s: cannot add AVP '%s' to message: %s", MODULE_NAME, target->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
158 return NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
159 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
160 fd_log_debug("%s: '%s' added", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
161 /* now find it in the new place */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
162 continue;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
163 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
164 location = new_location;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
165 fd_log_debug("%s: found '%s'", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
166 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
167 target = target->child;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
168 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
169 fd_log_debug("%s: returning AVP for '%s'", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
170 return location;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
171 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
172
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
173 static int store_apply(msg_or_avp *msg, struct store **store)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
174 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
175 while (*store) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
176 msg_or_avp *container;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
177 struct store *next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
178 if ((*store)->avp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
179 int ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
180 if ((container=find_container(msg, (*store)->target)) == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
181 fd_log_error("%s: internal error, container not found", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
182 return -1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
183 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
184
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
185 if ((ret=fd_msg_avp_add(container, MSG_BRW_LAST_CHILD, (*store)->avp)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
186 fd_log_error("%s: cannot add AVP '%s' to message: %s", MODULE_NAME, (*store)->target->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
187 return -1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
188 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
189 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
190 next = (*store)->next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
191 free(*store);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
192 *store = next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
193 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
194 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
195 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
196
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
197 static int schedule_for_adding(struct avp *avp, struct avp_target *target, struct store *store)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
198 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
199 if (store->avp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
200 struct store *new;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
201 if ((new=store_new()) == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
202 return -1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
203 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
204 new->avp = avp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
205 new->target = target;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
206 new->next = store->next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
207 store->next = new;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
208 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
209 store->avp = avp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
210 store->target = target;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
211 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
212 fd_log_debug("%s: noted %s for later adding", MODULE_NAME, target->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
213 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
214 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
215
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
216 static void move_avp_to_target(union avp_value *avp_value, struct avp_target *target, struct store *store)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
217 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
218 struct dict_object *avp_do;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
219 struct avp *avp;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
220 int ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
221 struct avp_target *final = target;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
222
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
223 while (final->child) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
224 final = final->child;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
225 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
226 if ((ret=fd_dict_search(fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME_ALL_VENDORS, final->name, &avp_do, ENOENT)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
227 fd_log_error("internal error, target AVP '%s' not in dictionary: %s", final->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
228 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
229 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
230 if ((ret=fd_msg_avp_new(avp_do, 0, &avp)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
231 fd_log_error("internal error, error creating structure for AVP '%s': %s", final->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
232 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
233 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
234 if ((ret=fd_msg_avp_setvalue(avp, avp_value)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
235 fd_log_error("internal error, cannot set value for AVP '%s': %s", final->name, strerror(ret));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
236 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
237 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
238 if (schedule_for_adding(avp, target, store) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
239 fd_log_error("internal error, cannot add AVP '%s' to message", final->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
240 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
241 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
242
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
243 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
244 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
245
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
246
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
247 static struct avp_match *avp_to_be_replaced(const char *avp_name, struct avp_match *subtree)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
248 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
249 struct avp_match *ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
250 for (ret=subtree; ret != NULL; ret=ret->next) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
251 if (strcmp(ret->name, avp_name) == 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
252 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
253 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
254 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
255 return NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
256 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
257
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
258 /*
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
259 * msg: whole message
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
260 * avp: current AVP in message
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
261 * subtree: comparison subtree
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
262 */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
263 static int replace_avps(struct msg *msg, msg_or_avp *avp, struct avp_match *subtree, struct store *store)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
264 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
265 int nothing_left = 1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
266 /* for each AVP in message */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
267 while (avp) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
268 struct avp_hdr *header = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
269 struct dict_object *model = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
270 const char *avp_name = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
271 msg_or_avp *next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
272 int delete = 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
273
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
274 if (fd_msg_avp_hdr(avp, &header) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
275 fd_log_notice("internal error: unable to get header for AVP");
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
276 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
277 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
278 if (fd_msg_model(avp, &model) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
279 fd_log_notice("internal error: unable to get model for AVP (%d, vendor %d)", header->avp_code, header->avp_vendor);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
280 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
281 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
282 if (model == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
283 fd_log_notice("unknown AVP (%d, vendor %d) (not in dictionary), skipping", header->avp_code, header->avp_vendor);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
284
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
285 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
286 struct dict_avp_data dictdata;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
287 struct avp_match *subtree_match;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
288 enum dict_avp_basetype basetype = AVP_TYPE_OCTETSTRING;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
289
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
290 fd_dict_getval(model, &dictdata);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
291 avp_name = dictdata.avp_name;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
292 basetype = dictdata.avp_basetype;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
293 /* check if it exists in the subtree */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
294 if ((subtree_match = avp_to_be_replaced(avp_name, subtree))) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
295 /* if this should be deleted, mark as such */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
296 if (subtree_match->drop) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
297 fd_log_notice("%s: dropping AVP '%s'", MODULE_NAME, avp_name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
298 delete = 1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
299 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
300 /* if grouped, dive down */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
301 if (basetype == AVP_TYPE_GROUPED) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
302 msg_or_avp *child = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
303
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
304 fd_log_debug("%s: grouped AVP '%s'", MODULE_NAME, avp_name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
305 if (fd_msg_browse(avp, MSG_BRW_FIRST_CHILD, &child, NULL) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
306 fd_log_notice("internal error: unable to browse message at AVP (%d, vendor %d)", header->avp_code, header->avp_vendor);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
307 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
308 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
309
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
310 /* replace_avps returns if the AVP was emptied out */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
311 if (replace_avps(msg, child, subtree_match->children, store)) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
312 fd_log_notice("%s: removing empty grouped AVP '%s'", MODULE_NAME, avp_name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
313 delete = 1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
314 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
315 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
316 else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
317 /* if single, remove it and add replacement AVP in target structure */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
318 if (subtree_match->target) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
319 struct avp_target *final = subtree_match->target;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
320 while (final->child) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
321 final = final->child;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
322 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
323 fd_log_notice("%s: moving AVP '%s' to '%s'", MODULE_NAME, avp_name, final->name);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
324 move_avp_to_target(header->avp_value, subtree_match->target, store);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
325 delete = 1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
326 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
327 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
328 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
329 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
330 fd_msg_browse(avp, MSG_BRW_NEXT, &next, NULL);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
331 if (delete) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
332 /* remove AVP from message */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
333 fd_msg_free((msg_or_avp *)avp);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
334 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
335 nothing_left = 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
336 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
337
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
338 avp = next;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
339 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
340
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
341 return nothing_left;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
342 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
343
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
344 static volatile int in_signal_handler = 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
345
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
346 /* signal handler */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
347 static void sig_hdlr(void)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
348 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
349 struct avp_match *old_config;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
350
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
351 if (in_signal_handler) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
352 fd_log_error("%s: already handling a signal, ignoring new one", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
353 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
354 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
355 in_signal_handler = 1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
356
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
357 if (pthread_rwlock_wrlock(&rt_rewrite_lock) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
358 fd_log_error("%s: locking failed, aborting config reload", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
359 return;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
360 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
361
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
362 /* save old config in case reload goes wrong */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
363 old_config = avp_match_start;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
364 avp_match_start = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
365
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
366 if (rt_rewrite_conf_handle(config_file) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
367 fd_log_notice("%s: error reloading configuration, restoring previous configuration", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
368 avp_match_free(avp_match_start);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
369 avp_match_start = old_config;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
370 } else {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
371 avp_match_free(old_config);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
372 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
373
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
374 if (pthread_rwlock_unlock(&rt_rewrite_lock) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
375 fd_log_error("%s: unlocking failed after config reload, exiting", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
376 exit(1);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
377 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
378
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
379 fd_log_notice("%s: reloaded configuration", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
380
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
381 in_signal_handler = 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
382 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
383
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
384 static int rt_rewrite(void * cbdata, struct msg **msg)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
385 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
386 int ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
387 msg_or_avp *avp = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
388 struct store *store = NULL;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
389
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
390 /* nothing configured */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
391 if (avp_match_start == NULL) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
392 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
393 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
394
1388
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
395 if (pthread_rwlock_wrlock(&rt_rewrite_lock) != 0) {
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
396 fd_log_error("%s: locking failed, aborting message rewrite", MODULE_NAME);
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
397 return errno;
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
398 }
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
399
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
400 if ((ret = fd_msg_parse_dict(*msg, fd_g_config->cnf_dict, NULL)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
401 fd_log_notice("%s: error parsing message", MODULE_NAME);
1388
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
402 pthread_rwlock_unlock(&rt_rewrite_lock);
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
403 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
404 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
405 if ((ret=fd_msg_browse(*msg, MSG_BRW_FIRST_CHILD, &avp, NULL)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
406 fd_log_notice("internal error: message has no child");
1388
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
407 pthread_rwlock_unlock(&rt_rewrite_lock);
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
408 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
409 }
1547
44bb63ba9c2c rt_rewrite: allocate object later to reduce cleanups
Thomas Klausner <tk@giga.or.at>
parents: 1424
diff changeset
410 if ((store=store_new()) == NULL) {
44bb63ba9c2c rt_rewrite: allocate object later to reduce cleanups
Thomas Klausner <tk@giga.or.at>
parents: 1424
diff changeset
411 fd_log_error("%s: malloc failure");
44bb63ba9c2c rt_rewrite: allocate object later to reduce cleanups
Thomas Klausner <tk@giga.or.at>
parents: 1424
diff changeset
412 pthread_rwlock_unlock(&rt_rewrite_lock);
44bb63ba9c2c rt_rewrite: allocate object later to reduce cleanups
Thomas Klausner <tk@giga.or.at>
parents: 1424
diff changeset
413 return ENOMEM;
44bb63ba9c2c rt_rewrite: allocate object later to reduce cleanups
Thomas Klausner <tk@giga.or.at>
parents: 1424
diff changeset
414 }
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
415 if (replace_avps(*msg, avp, avp_match_start->children, store) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
416 fd_log_error("%s: replace AVP function failed", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
417 store_free(store);
1388
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
418 pthread_rwlock_unlock(&rt_rewrite_lock);
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
419 return -1;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
420 }
1388
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
421 ret = store_apply(*msg, &store);
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
422
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
423 if (pthread_rwlock_unlock(&rt_rewrite_lock) != 0) {
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
424 fd_log_error("%s: unlocking failed, returning error", MODULE_NAME);
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
425 return errno;
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
426 }
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
427
61e693afccc6 rt_rewrite: improve locking
Thomas Klausner <tk@giga.or.at>
parents: 1341
diff changeset
428 return ret;
1341
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
429 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
430
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
431 /* entry point */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
432 static int rt_rewrite_entry(char * conffile)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
433 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
434 int ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
435 config_file = conffile;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
436
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
437 pthread_rwlock_init(&rt_rewrite_lock, NULL);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
438
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
439 if (pthread_rwlock_wrlock(&rt_rewrite_lock) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
440 fd_log_notice("%s: write-lock failed, aborting", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
441 return EDEADLK;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
442 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
443
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
444 /* Parse the configuration file */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
445 if ((ret=rt_rewrite_conf_handle(config_file)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
446 pthread_rwlock_unlock(&rt_rewrite_lock);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
447 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
448 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
449
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
450 if (pthread_rwlock_unlock(&rt_rewrite_lock) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
451 fd_log_notice("%s: write-unlock failed, aborting", MODULE_NAME);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
452 return EDEADLK;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
453 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
454
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
455 /* Register reload callback */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
456 CHECK_FCT(fd_event_trig_regcb(SIGUSR1, MODULE_NAME, sig_hdlr));
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
457
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
458 /* Register the callback */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
459 if ((ret=fd_rt_fwd_register(rt_rewrite, NULL, RT_FWD_ALL, &rt_rewrite_handle)) != 0) {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
460 fd_log_error("Cannot register callback handler");
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
461 return ret;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
462 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
463
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
464 fd_log_notice("Extension 'Rewrite' initialized");
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
465 return 0;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
466 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
467
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
468 /* Unload */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
469 void fd_ext_fini(void)
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
470 {
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
471 /* Unregister the callbacks */
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
472 fd_rt_fwd_unregister(rt_rewrite_handle, NULL);
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
473 return ;
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
474 }
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
475
b0401251d8c0 rt_rewrite: new extension
Thomas Klausner <tk@giga.or.at>
parents:
diff changeset
476 EXTENSION_ENTRY("rt_rewrite", rt_rewrite_entry);
"Welcome to our mercurial repository"