Browse code

- reduced dns structure sizes and re-ordered them to waste less space - possible memory leak fixed (could appear only when resolving srv or naptr records and the dns response packet is corrupted)

Andrei Pelinescu-Onciul authored on 13/07/2006 18:30:02
Showing 4 changed files
... ...
@@ -66,7 +66,7 @@ MAIN_NAME=ser
66 66
 VERSION = 0
67 67
 PATCHLEVEL = 10
68 68
 SUBLEVEL =   99
69
-EXTRAVERSION = -dev41
69
+EXTRAVERSION = -dev42
70 70
 
71 71
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
72 72
 			$(SUBLEVEL) )
... ...
@@ -31,6 +31,7 @@
31 31
  *  2003-07-03  default port value set according to proto (andrei)
32 32
  *  2005-07-11  added resolv_init (timeouts a.s.o) (andrei)
33 33
  *  2006-04-13  added sip_hostport2su()  (andrei)
34
+ *  2006-07-13  rdata structures put on diet (andrei)
34 35
  */ 
35 36
 
36 37
 
... ...
@@ -146,26 +147,37 @@ struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end,
146 147
 								  unsigned char* rdata)
147 148
 {
148 149
 	struct srv_rdata* srv;
150
+	unsigned short priority;
151
+	unsigned short weight;
152
+	unsigned short port;
149 153
 	int len;
154
+	char name[MAX_DNS_NAME];
150 155
 	
151 156
 	srv=0;
152 157
 	if ((rdata+6)>=end) goto error;
153
-	srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata));
158
+	
159
+	memcpy((void*)&priority, rdata, 2);
160
+	memcpy((void*)&weight,   rdata+2, 2);
161
+	memcpy((void*)&port,     rdata+4, 2);
162
+	rdata+=6;
163
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)<0)
164
+		goto error;
165
+	len=strlen(name);
166
+	if (len>255)
167
+		goto error;
168
+	/* alloc enought space for the struct + null terminated name */
169
+	srv=local_malloc(sizeof(struct srv_rdata)-1+len+1);
154 170
 	if (srv==0){
155 171
 		LOG(L_ERR, "ERROR: dns_srv_parser: out of memory\n");
156 172
 		goto error;
157 173
 	}
174
+	srv->priority=ntohs(priority);
175
+	srv->weight=ntohs(weight);
176
+	srv->port=ntohs(port);
177
+	srv->name_len=len;
178
+	memcpy(srv->name, name, srv->name_len);
179
+	srv->name[srv->name_len]=0;
158 180
 	
159
-	memcpy((void*)&srv->priority, rdata, 2);
160
-	memcpy((void*)&srv->weight,   rdata+2, 2);
161
-	memcpy((void*)&srv->port,     rdata+4, 2);
162
-	rdata+=6;
163
-	srv->priority=ntohs(srv->priority);
164
-	srv->weight=ntohs(srv->weight);
165
-	srv->port=ntohs(srv->port);
166
-	if ((len=dn_expand(msg, end, rdata, srv->name, MAX_DNS_NAME-1))==-1)
167
-		goto error;
168
-	/* add terminating 0 ? (warning: len=compressed name len) */
169 181
 	return srv;
170 182
 error:
171 183
 	if (srv) local_free(srv);
... ...
@@ -203,36 +215,63 @@ struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
203 215
 								  unsigned char* rdata)
204 216
 {
205 217
 	struct naptr_rdata* naptr;
218
+	unsigned char* flags;
219
+	unsigned char* services;
220
+	unsigned char* regexp;
221
+	unsigned short order;
222
+	unsigned short pref;
223
+	unsigned char flags_len;
224
+	unsigned char services_len;
225
+	unsigned char regexp_len;
206 226
 	int len;
227
+	char repl[MAX_DNS_NAME];
207 228
 	
208 229
 	naptr = 0;
209 230
 	if ((rdata + 7) >= end) goto error;
210
-	naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata));
231
+	
232
+	memcpy((void*)&order, rdata, 2);
233
+	memcpy((void*)&pref, rdata + 2, 2);
234
+	flags_len = rdata[4];
235
+	if ((rdata + 7 +  flags_len) >= end)
236
+		goto error;
237
+	flags=rdata+5;
238
+	services_len = rdata[5 + flags_len];
239
+	if ((rdata + 7 + flags_len + services_len) >= end)
240
+		goto error;
241
+	services=rdata + 6 + flags_len;
242
+	regexp_len = rdata[6 + flags_len + services_len];
243
+	if ((rdata + 7 + flags_len + services_len + regexp_len) >= end)
244
+		goto error;
245
+	regexp=rdata + 7 + flags_len + services_len;
246
+	rdata = rdata + 7 + flags_len + services_len + regexp_len;
247
+	if (dn_expand(msg, end, rdata, repl, MAX_DNS_NAME-1) == -1)
248
+		goto error;
249
+	len=strlen(repl);
250
+	if (len>255)
251
+		goto error;
252
+	naptr=local_malloc(sizeof(struct naptr_rdata)+flags_len+services_len+
253
+						regexp_len+len+1-1);
211 254
 	if (naptr == 0){
212 255
 		LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n");
213 256
 		goto error;
214 257
 	}
215
-	
216
-	memcpy((void*)&naptr->order, rdata, 2);
217 258
 	naptr->order=ntohs(naptr->order);
218
-	memcpy((void*)&naptr->pref, rdata + 2, 2);
219 259
 	naptr->pref=ntohs(naptr->pref);
220
-	naptr->flags_len = (int)rdata[4];
221
-	if ((rdata + 7 +  naptr->flags_len) >= end) goto error;
222
-	memcpy((void*)&naptr->flags, rdata + 5, naptr->flags_len);
223
-	naptr->services_len = (int)rdata[5 + naptr->flags_len];
224
-	if ((rdata + 7 + naptr->flags_len + naptr->services_len) >= end) goto error;
225
-	memcpy((void*)&naptr->services, rdata + 6 + naptr->flags_len, naptr->services_len);
226
-	naptr->regexp_len = (int)rdata[6 + naptr->flags_len + naptr->services_len];
227
-	if ((rdata + 7 + naptr->flags_len + naptr->services_len +
228
-					naptr->regexp_len) >= end) goto error;
229
-	memcpy((void*)&naptr->regexp, rdata + 7 + naptr->flags_len +
230
-				naptr->services_len, naptr->regexp_len);
231
-	rdata = rdata + 7 + naptr->flags_len + naptr->services_len + 
232
-			naptr->regexp_len;
233
-	if ((len=dn_expand(msg, end, rdata, naptr->repl, MAX_DNS_NAME-1)) == -1)
234
-		goto error;
235
-	/* add terminating 0 ? (warning: len=compressed name len) */
260
+	
261
+	naptr->flags=&naptr->str_table[0];
262
+	naptr->flags_len=flags_len;
263
+	memcpy(naptr->flags, flags, naptr->flags_len);
264
+	naptr->services=&naptr->str_table[flags_len];
265
+	naptr->services_len=services_len;
266
+	memcpy(naptr->services, services, naptr->services_len);
267
+	naptr->regexp=&naptr->str_table[flags_len+services_len];
268
+	naptr->regexp_len=regexp_len;
269
+	memcpy(naptr->regexp, regexp, naptr->regexp_len);
270
+	naptr->repl=&naptr->str_table[flags_len+services_len+regexp_len];
271
+	naptr->repl_len=len;
272
+	memcpy(naptr->repl, repl, len);
273
+	naptr->repl[len]=0; /* null term. */
274
+	
236 275
 	return naptr;
237 276
 error:
238 277
 	if (naptr) local_free(naptr);
... ...
@@ -247,15 +286,23 @@ struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
247 286
 {
248 287
 	struct cname_rdata* cname;
249 288
 	int len;
289
+	char name[MAX_DNS_NAME];
250 290
 	
251 291
 	cname=0;
252
-	cname=(struct cname_rdata*)local_malloc(sizeof(struct cname_rdata));
292
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
293
+		goto error;
294
+	len=strlen(name);
295
+	if (len>255)
296
+		goto error;
297
+	/* alloc sizeof struct + space for the null terminated name */
298
+	cname=local_malloc(sizeof(struct cname_rdata)-1+len+1);
253 299
 	if(cname==0){
254 300
 		LOG(L_ERR, "ERROR: dns_cname_parser: out of memory\n");
255 301
 		goto error;
256 302
 	}
257
-	if ((len=dn_expand(msg, end, rdata, cname->name, MAX_DNS_NAME-1))==-1)
258
-		goto error;
303
+	cname->name_len=len;
304
+	memcpy(cname->name, name, cname->name_len);
305
+	cname->name[cname->name_len]=0;
259 306
 	return cname;
260 307
 error:
261 308
 	if (cname) local_free(cname);
... ...
@@ -431,6 +478,8 @@ struct rdata* get_record(char* name, int type)
431 478
 				
432 479
 				/* insert sorted into the list */
433 480
 				for (crt=&head; *crt; crt= &((*crt)->next)){
481
+					if ((*crt)->type!=T_SRV)
482
+						continue;
434 483
 					crt_srv=(struct srv_rdata*)(*crt)->rdata;
435 484
 					if ((srv_rd->priority <  crt_srv->priority) ||
436 485
 					   ( (srv_rd->priority == crt_srv->priority) && 
... ...
@@ -483,6 +532,7 @@ struct rdata* get_record(char* name, int type)
483 532
 	return head;
484 533
 error_boundary:
485 534
 		LOG(L_ERR, "ERROR: get_record: end of query buff reached\n");
535
+		if (head) free_rdata_list(head);
486 536
 		return 0;
487 537
 error_parse:
488 538
 		LOG(L_ERR, "ERROR: get_record: rdata parse error \n");
... ...
@@ -30,6 +30,7 @@
30 30
  * --------
31 31
  *  2003-04-12  support for resolving ipv6 address references added (andrei)
32 32
  *  2004-07-28  darwin needs nameser_compat.h (andrei)
33
+ *  2006-07-13  rdata structures put on diet (andrei)
33 34
  */
34 35
 
35 36
 
... ...
@@ -79,24 +80,39 @@ struct srv_rdata {
79 80
 	unsigned short priority;
80 81
 	unsigned short weight;
81 82
 	unsigned short port;
82
-	unsigned int name_len;
83
-	char name[MAX_DNS_NAME];
83
+	unsigned char name_len; /* name length w/o the terminating 0 */
84
+	char name[1]; /* null terminated name (len=name_len+1) */
84 85
 };
85 86
 
87
+
88
+/* real size of the structure */
89
+#define SRV_RDATA_SIZE (s) (sizeof(struct srv_rdata)+(s).name_len)
90
+
86 91
 /* naptr rec. struct*/
87 92
 struct naptr_rdata {
93
+	char* flags;    /* points inside str_table */
94
+	char* services; /* points inside str_table */
95
+	char* regexp;   /* points inside str_table */
96
+	char* repl;     /* points inside str_table, null terminated */
97
+	
88 98
 	unsigned short order;
89 99
 	unsigned short pref;
90
-	unsigned int flags_len;
91
-	char flags[MAX_DNS_STRING];
92
-	unsigned int services_len;
93
-	char services[MAX_DNS_STRING];
94
-	unsigned int regexp_len;
95
-	char regexp[MAX_DNS_STRING];
96
-	unsigned int repl_len; /* not currently used */
97
-	char repl[MAX_DNS_NAME];
100
+	
101
+	unsigned char flags_len;
102
+	unsigned char services_len;
103
+	unsigned char regexp_len;
104
+	unsigned char repl_len; /* not currently used */
105
+	
106
+	char str_table[1]; /* contains all the strings */
98 107
 };
99 108
 
109
+/* real size of the structure */
110
+#define NAPTR_RDATA_SIZE (s) (sizeof(struct naptr_rdata) \
111
+								+ (s).flags_len \
112
+								+ (s).services_len \
113
+								+ (s).regexp_len \
114
+								+ (s).repl_len + 1 - 1)
115
+
100 116
 
101 117
 /* A rec. struct */
102 118
 struct a_rdata {
... ...
@@ -109,9 +125,13 @@ struct aaaa_rdata {
109 125
 
110 126
 /* cname rec. struct*/
111 127
 struct cname_rdata {
112
-	char name[MAX_DNS_NAME];
128
+	unsigned char name_len; /* name length w/o the terminating 0 */
129
+	char name[1]; /* null terminated name (len=name_len+1) */
113 130
 };
114 131
 
132
+/* real size of the structure */
133
+#define CNAME_RDATA_SIZE (s) (sizeof(struct cname_rdata)+(s).name_len)
134
+
115 135
 
116 136
 
117 137
 struct rdata* get_record(char* name, int type);
... ...
@@ -31,8 +31,11 @@
31 31
  * along with this program; if not, write to the Free Software 
32 32
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33 33
  */
34
+/*
35
+ * tester for ser resolver  (andrei) */
34 36
 
35 37
 
38
+#include <ctype.h>
36 39
 #include <stdio.h>
37 40
 #include <stdlib.h>
38 41
 #include <errno.h>
... ...
@@ -50,6 +53,11 @@ int process_no=0;
50 53
 long shm_mem_size=0;
51 54
 char mem_pool[1024*1024];
52 55
 struct qm_block* mem_block;
56
+int log_facility=0;
57
+int memlog=0;
58
+int memdbg=0;
59
+int ser_error=0;
60
+struct process_table* pt=0;
53 61
 
54 62
 
55 63
 static char* id="$Id$";
... ...
@@ -74,6 +82,7 @@ int main(int argc, char** argv)
74 82
 	struct rdata* head;
75 83
 	struct rdata* l;
76 84
 	struct srv_rdata* srv;
85
+	struct naptr_rdata* naptr;
77 86
 	struct a_rdata* ip;
78 87
 
79 88
 	name=type_str=0;
... ...
@@ -154,7 +163,9 @@ int main(int argc, char** argv)
154 163
 							l->type, l->class, l->ttl);
155 164
 					printf("       prio= %d weight=%d port=%d\n",
156 165
 								srv->priority, srv->weight, srv->port);
157
-					printf("       name= [%s]\n", srv->name);
166
+					printf("       name_len= %d (%d), name= [%.*s]\n",
167
+									srv->name_len, strlen(srv->name),
168
+									srv->name_len, srv->name);
158 169
 					break;
159 170
 				case T_CNAME:
160 171
 					printf("CNAME  type= %d class=%d  ttl=%d\n",
... ...
@@ -170,13 +181,32 @@ int main(int argc, char** argv)
170 181
 								ip->ip[0], ip->ip[1], ip->ip[2], ip->ip[3]);
171 182
 					break;
172 183
 				case T_AAAA:
173
-					printf("AAAA    type= %d class=%d  ttl=%d\n",
184
+					printf("AAAA   type= %d class=%d  ttl=%d\n",
174 185
 							l->type, l->class, l->ttl);
175 186
 					printf("        ip6= ");
176 187
 					for(r=0;r<16;r++) 
177 188
 						printf("%x ", ((struct aaaa_rdata*)l->rdata)->ip6[r]);
178 189
 					printf("\n");
179 190
 					break;
191
+				case T_NAPTR:
192
+					naptr=(struct naptr_rdata*)l->rdata;
193
+					printf("NAPTR  type= %d class=%d  ttl=%d\n",
194
+							l->type, l->class, l->ttl);
195
+					printf("       order= %d pref=%d\n",
196
+								naptr->order, naptr->pref);
197
+					printf("       flags_len= %d,     flags= [%.*s]\n",
198
+									naptr->flags_len, 
199
+									naptr->flags_len, naptr->flags);
200
+					printf("       services_len= %d,  services= [%.*s]\n",
201
+									naptr->services_len, 
202
+									naptr->services_len, naptr->services);
203
+					printf("       regexp_len= %d,    regexp= [%.*s]\n",
204
+									naptr->regexp_len, 
205
+									naptr->regexp_len, naptr->regexp);
206
+					printf("       repl_len= %d,      repl= [%s]\n",
207
+									naptr->repl_len, naptr->repl);
208
+					break;
209
+
180 210
 				default:
181 211
 					printf("UNKN    type= %d class=%d  ttl=%d\n",
182 212
 								l->type, l->class, l->ttl);