Browse code

- extracted inline function from parse_rr() to parse only the body of the header - parse_rr() calls now this function - wrapper to the inline function so that can be called from everywhere - duplicate_rr functions duplicates the whole likend list of routes, if applicable

Daniel-Constantin Mierla authored on 29/10/2003 12:25:31
Showing 2 changed files
... ...
@@ -27,6 +27,12 @@
27 27
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 28
  */
29 29
 
30
+/**
31
+ * History:
32
+ * --------
33
+ * 2003-10-07  parse_rr() splited and added parse_rr_body()
34
+ * 2003-10-21  duplicate_rr() duplicate the whole linked list of RR
35
+ */
30 36
 #include <string.h>
31 37
 #include "parse_rr.h"
32 38
 #include "../mem/mem.h"
... ...
@@ -36,27 +42,23 @@
36 36
 #include "../ut.h"
37 37
 
38 38
 /*
39
- * Parse Route and Record-Route header fields
39
+ * Parse Route or Record-Route body
40 40
  */
41
-int parse_rr(struct hdr_field* _h)
41
+static inline int do_parse_rr_body(char *buf, int len, rr_t **head)
42 42
 {
43 43
 	rr_t* r, *last;
44 44
 	str s;
45 45
 	param_hooks_t hooks;
46 46
 
47
-	if (!_h) {
48
-		LOG(L_ERR, "parse_rr(): Invalid parameter value\n");
49
-		return -1;
50
-	}
51
-
52
-	if (_h->parsed) {
53
-		     /* Already parsed, return */
47
+	/* Make a temporary copy of the string pointer */
48
+	if(buf==0 || len<=0)
49
+	{
50
+		DBG("parse_rr_body(): No body for record-route\n");
51
+		*head = 0;
54 52
 		return 0;
55 53
 	}
56
-
57
-	     /* Make a temporary copy of the string pointer */
58
-	s.s = _h->body.s;
59
-	s.len = _h->body.len;
54
+	s.s = buf;
55
+	s.len = len;
60 56
 	trim_leading(&s);
61 57
 
62 58
 	last = 0;
... ...
@@ -118,22 +120,52 @@ int parse_rr(struct hdr_field* _h)
118 118
 		}
119 119
 
120 120
 		     /* Append the structure as last parameter of the linked list */
121
-		if (!_h->parsed) _h->parsed = (void*)r;
121
+		if (!*head) *head = r;
122 122
 		if (last) last->next = r;
123 123
 		last = r;
124 124
 	}
125 125
 
126 126
  error:
127 127
 	if (r) pkg_free(r);
128
-	free_rr((rr_t**)&_h->parsed); /* Free any contacts created so far */
128
+	free_rr(head); /* Free any contacts created so far */
129 129
 	return -1;
130 130
 
131 131
  ok:
132
-	if (!_h->parsed) _h->parsed = (void*)r;
132
+	if (!*head) *head = r;
133 133
 	if (last) last->next = r;
134 134
 	return 0;
135 135
 }
136 136
 
137
+/*
138
+ * Wrapper to do_parse_rr_body() for external calls
139
+ */
140
+int parse_rr_body(char *buf, int len, rr_t **head)
141
+{
142
+	return do_parse_rr_body(buf, len, head);
143
+}
144
+
145
+/*
146
+ * Parse Route and Record-Route header fields
147
+ */
148
+int parse_rr(struct hdr_field* _h)
149
+{
150
+	rr_t* r = NULL;
151
+
152
+	if (!_h) {
153
+		LOG(L_ERR, "parse_rr(): Invalid parameter value\n");
154
+		return -1;
155
+	}
156
+
157
+	if (_h->parsed) {
158
+		     /* Already parsed, return */
159
+		return 0;
160
+	}
161
+
162
+	if(do_parse_rr_body(_h->body.s, _h->body.len, &r) < 0)
163
+		return -1;
164
+	_h->parsed = (void*)r;
165
+	return 0;
166
+}
137 167
 
138 168
 /*
139 169
  * Free list of rrs
... ...
@@ -226,45 +258,57 @@ static inline void xlate_pointers(rr_t* _orig, rr_t* _r)
226 226
 static inline int do_duplicate_rr(rr_t** _new, rr_t* _r, int _shm)
227 227
 {
228 228
 	int len, ret;
229
-	rr_t* res;
229
+	rr_t* res, *prev, *it;
230 230
 
231 231
 	if (!_new || !_r) {
232 232
 		LOG(L_ERR, "duplicate_rr(): Invalid parameter value\n");
233 233
 		return -1;
234 234
 	}
235
+	prev  = NULL;
236
+	*_new = NULL;
237
+	it    = _r;
238
+	while(it)
239
+	{
240
+		if (it->params) {
241
+			len = it->params->name.s + it->params->len - it->nameaddr.name.s;
242
+		} else {
243
+			len = it->nameaddr.len;
244
+		}
235 245
 
236
-	if (_r->params) {
237
-		len = _r->params->name.s + _r->params->len - _r->nameaddr.name.s;
238
-	} else {
239
-		len = _r->nameaddr.len;
240
-	}
246
+		if (_shm) res = shm_malloc(sizeof(rr_t) + len);
247
+		else res = pkg_malloc(sizeof(rr_t) + len);
248
+		if (!res) {
249
+			LOG(L_ERR, "duplicate_rr(): No memory left\n");
250
+			return -2;
251
+		}
252
+		memcpy(res, it, sizeof(rr_t));
241 253
 
242
-	if (_shm) res = shm_malloc(sizeof(rr_t) + len);
243
-	else res = pkg_malloc(sizeof(rr_t) + len);
244
-	if (!res) {
245
-		LOG(L_ERR, "duplicate_rr(): No memory left\n");
246
-		return -2;
247
-	}
248
-	memcpy(res, _r, sizeof(rr_t));
254
+		res->nameaddr.name.s = (char*)res + sizeof(rr_t);
255
+		memcpy(res->nameaddr.name.s, it->nameaddr.name.s, len);
249 256
 
250
-        res->nameaddr.name.s = (char*)res + sizeof(rr_t);
251
-	memcpy(res->nameaddr.name.s, _r->nameaddr.name.s, len);
257
+		if (_shm) {
258
+			ret = shm_duplicate_params(&res->params, it->params);
259
+		} else {
260
+			ret = duplicate_params(&res->params, it->params);
261
+		}
252 262
 
253
-	if (_shm) {
254
-		ret = shm_duplicate_params(&res->params, _r->params);
255
-	} else {
256
-		ret = duplicate_params(&res->params, _r->params);
257
-	}
263
+		if (ret < 0) {
264
+			LOG(L_ERR, "duplicate_rr(): Error while duplicating parameters\n");
265
+			if (_shm) shm_free(res);
266
+			else pkg_free(res);
267
+			return -3;
268
+		}
258 269
 
259
-	if (ret < 0) {
260
-		LOG(L_ERR, "Error while duplicating parameters\n");
261
-		if (_shm) shm_free(res);
262
-		else pkg_free(res);
263
-		return -3;
264
-	}
270
+		xlate_pointers(it, res);
265 271
 
266
-	xlate_pointers(_r, res);
267
-	*_new = res;
272
+		res->next=NULL;
273
+		if(*_new==NULL)
274
+			*_new = res;
275
+		if(prev)
276
+			prev->next = res;
277
+		prev = res;
278
+		it = it->next;
279
+	}
268 280
 	return 0;
269 281
 }
270 282
 
... ...
@@ -46,7 +46,7 @@ typedef struct rr {
46 46
 	param_t* r2;          /* Hook to r2 parameter */
47 47
 	param_t* params;      /* Linked list of other parameters */
48 48
 	int len;              /* Length of the whole route field */
49
-        struct rr* next;      /* Next RR in the list */
49
+	struct rr* next;      /* Next RR in the list */
50 50
 } rr_t;
51 51
 
52 52
 
... ...
@@ -55,6 +55,10 @@ typedef struct rr {
55 55
  */
56 56
 int parse_rr(struct hdr_field* _r);
57 57
 
58
+/*
59
+ * Parse the body of Route & Record-Route headers
60
+ */
61
+int parse_rr_body(char *buf, int len, rr_t **head);
58 62
 
59 63
 /*
60 64
  * Free list of rr