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 146
 								  unsigned char* rdata)
147 147
 {
148 148
 	struct srv_rdata* srv;
149
+	unsigned short priority;
150
+	unsigned short weight;
151
+	unsigned short port;
149 152
 	int len;
153
+	char name[MAX_DNS_NAME];
150 154
 	
151 155
 	srv=0;
152 156
 	if ((rdata+6)>=end) goto error;
153
-	srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata));
157
+	
158
+	memcpy((void*)&priority, rdata, 2);
159
+	memcpy((void*)&weight,   rdata+2, 2);
160
+	memcpy((void*)&port,     rdata+4, 2);
161
+	rdata+=6;
162
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)<0)
163
+		goto error;
164
+	len=strlen(name);
165
+	if (len>255)
166
+		goto error;
167
+	/* alloc enought space for the struct + null terminated name */
168
+	srv=local_malloc(sizeof(struct srv_rdata)-1+len+1);
154 169
 	if (srv==0){
155 170
 		LOG(L_ERR, "ERROR: dns_srv_parser: out of memory\n");
156 171
 		goto error;
157 172
 	}
173
+	srv->priority=ntohs(priority);
174
+	srv->weight=ntohs(weight);
175
+	srv->port=ntohs(port);
176
+	srv->name_len=len;
177
+	memcpy(srv->name, name, srv->name_len);
178
+	srv->name[srv->name_len]=0;
158 179
 	
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 180
 	return srv;
170 181
 error:
171 182
 	if (srv) local_free(srv);
... ...
@@ -203,36 +215,63 @@ struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end,
203 203
 								  unsigned char* rdata)
204 204
 {
205 205
 	struct naptr_rdata* naptr;
206
+	unsigned char* flags;
207
+	unsigned char* services;
208
+	unsigned char* regexp;
209
+	unsigned short order;
210
+	unsigned short pref;
211
+	unsigned char flags_len;
212
+	unsigned char services_len;
213
+	unsigned char regexp_len;
206 214
 	int len;
215
+	char repl[MAX_DNS_NAME];
207 216
 	
208 217
 	naptr = 0;
209 218
 	if ((rdata + 7) >= end) goto error;
210
-	naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata));
219
+	
220
+	memcpy((void*)&order, rdata, 2);
221
+	memcpy((void*)&pref, rdata + 2, 2);
222
+	flags_len = rdata[4];
223
+	if ((rdata + 7 +  flags_len) >= end)
224
+		goto error;
225
+	flags=rdata+5;
226
+	services_len = rdata[5 + flags_len];
227
+	if ((rdata + 7 + flags_len + services_len) >= end)
228
+		goto error;
229
+	services=rdata + 6 + flags_len;
230
+	regexp_len = rdata[6 + flags_len + services_len];
231
+	if ((rdata + 7 + flags_len + services_len + regexp_len) >= end)
232
+		goto error;
233
+	regexp=rdata + 7 + flags_len + services_len;
234
+	rdata = rdata + 7 + flags_len + services_len + regexp_len;
235
+	if (dn_expand(msg, end, rdata, repl, MAX_DNS_NAME-1) == -1)
236
+		goto error;
237
+	len=strlen(repl);
238
+	if (len>255)
239
+		goto error;
240
+	naptr=local_malloc(sizeof(struct naptr_rdata)+flags_len+services_len+
241
+						regexp_len+len+1-1);
211 242
 	if (naptr == 0){
212 243
 		LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n");
213 244
 		goto error;
214 245
 	}
215
-	
216
-	memcpy((void*)&naptr->order, rdata, 2);
217 246
 	naptr->order=ntohs(naptr->order);
218
-	memcpy((void*)&naptr->pref, rdata + 2, 2);
219 247
 	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) */
248
+	
249
+	naptr->flags=&naptr->str_table[0];
250
+	naptr->flags_len=flags_len;
251
+	memcpy(naptr->flags, flags, naptr->flags_len);
252
+	naptr->services=&naptr->str_table[flags_len];
253
+	naptr->services_len=services_len;
254
+	memcpy(naptr->services, services, naptr->services_len);
255
+	naptr->regexp=&naptr->str_table[flags_len+services_len];
256
+	naptr->regexp_len=regexp_len;
257
+	memcpy(naptr->regexp, regexp, naptr->regexp_len);
258
+	naptr->repl=&naptr->str_table[flags_len+services_len+regexp_len];
259
+	naptr->repl_len=len;
260
+	memcpy(naptr->repl, repl, len);
261
+	naptr->repl[len]=0; /* null term. */
262
+	
236 263
 	return naptr;
237 264
 error:
238 265
 	if (naptr) local_free(naptr);
... ...
@@ -247,15 +286,23 @@ struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end,
247 247
 {
248 248
 	struct cname_rdata* cname;
249 249
 	int len;
250
+	char name[MAX_DNS_NAME];
250 251
 	
251 252
 	cname=0;
252
-	cname=(struct cname_rdata*)local_malloc(sizeof(struct cname_rdata));
253
+	if (dn_expand(msg, end, rdata, name, MAX_DNS_NAME-1)==-1)
254
+		goto error;
255
+	len=strlen(name);
256
+	if (len>255)
257
+		goto error;
258
+	/* alloc sizeof struct + space for the null terminated name */
259
+	cname=local_malloc(sizeof(struct cname_rdata)-1+len+1);
253 260
 	if(cname==0){
254 261
 		LOG(L_ERR, "ERROR: dns_cname_parser: out of memory\n");
255 262
 		goto error;
256 263
 	}
257
-	if ((len=dn_expand(msg, end, rdata, cname->name, MAX_DNS_NAME-1))==-1)
258
-		goto error;
264
+	cname->name_len=len;
265
+	memcpy(cname->name, name, cname->name_len);
266
+	cname->name[cname->name_len]=0;
259 267
 	return cname;
260 268
 error:
261 269
 	if (cname) local_free(cname);
... ...
@@ -431,6 +478,8 @@ struct rdata* get_record(char* name, int type)
431 431
 				
432 432
 				/* insert sorted into the list */
433 433
 				for (crt=&head; *crt; crt= &((*crt)->next)){
434
+					if ((*crt)->type!=T_SRV)
435
+						continue;
434 436
 					crt_srv=(struct srv_rdata*)(*crt)->rdata;
435 437
 					if ((srv_rd->priority <  crt_srv->priority) ||
436 438
 					   ( (srv_rd->priority == crt_srv->priority) && 
... ...
@@ -483,6 +532,7 @@ struct rdata* get_record(char* name, int type)
483 483
 	return head;
484 484
 error_boundary:
485 485
 		LOG(L_ERR, "ERROR: get_record: end of query buff reached\n");
486
+		if (head) free_rdata_list(head);
486 487
 		return 0;
487 488
 error_parse:
488 489
 		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 79
 	unsigned short priority;
80 80
 	unsigned short weight;
81 81
 	unsigned short port;
82
-	unsigned int name_len;
83
-	char name[MAX_DNS_NAME];
82
+	unsigned char name_len; /* name length w/o the terminating 0 */
83
+	char name[1]; /* null terminated name (len=name_len+1) */
84 84
 };
85 85
 
86
+
87
+/* real size of the structure */
88
+#define SRV_RDATA_SIZE (s) (sizeof(struct srv_rdata)+(s).name_len)
89
+
86 90
 /* naptr rec. struct*/
87 91
 struct naptr_rdata {
92
+	char* flags;    /* points inside str_table */
93
+	char* services; /* points inside str_table */
94
+	char* regexp;   /* points inside str_table */
95
+	char* repl;     /* points inside str_table, null terminated */
96
+	
88 97
 	unsigned short order;
89 98
 	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];
99
+	
100
+	unsigned char flags_len;
101
+	unsigned char services_len;
102
+	unsigned char regexp_len;
103
+	unsigned char repl_len; /* not currently used */
104
+	
105
+	char str_table[1]; /* contains all the strings */
98 106
 };
99 107
 
108
+/* real size of the structure */
109
+#define NAPTR_RDATA_SIZE (s) (sizeof(struct naptr_rdata) \
110
+								+ (s).flags_len \
111
+								+ (s).services_len \
112
+								+ (s).regexp_len \
113
+								+ (s).repl_len + 1 - 1)
114
+
100 115
 
101 116
 /* A rec. struct */
102 117
 struct a_rdata {
... ...
@@ -109,9 +125,13 @@ struct aaaa_rdata {
109 109
 
110 110
 /* cname rec. struct*/
111 111
 struct cname_rdata {
112
-	char name[MAX_DNS_NAME];
112
+	unsigned char name_len; /* name length w/o the terminating 0 */
113
+	char name[1]; /* null terminated name (len=name_len+1) */
113 114
 };
114 115
 
116
+/* real size of the structure */
117
+#define CNAME_RDATA_SIZE (s) (sizeof(struct cname_rdata)+(s).name_len)
118
+
115 119
 
116 120
 
117 121
 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 50
 long shm_mem_size=0;
51 51
 char mem_pool[1024*1024];
52 52
 struct qm_block* mem_block;
53
+int log_facility=0;
54
+int memlog=0;
55
+int memdbg=0;
56
+int ser_error=0;
57
+struct process_table* pt=0;
53 58
 
54 59
 
55 60
 static char* id="$Id$";
... ...
@@ -74,6 +82,7 @@ int main(int argc, char** argv)
74 74
 	struct rdata* head;
75 75
 	struct rdata* l;
76 76
 	struct srv_rdata* srv;
77
+	struct naptr_rdata* naptr;
77 78
 	struct a_rdata* ip;
78 79
 
79 80
 	name=type_str=0;
... ...
@@ -154,7 +163,9 @@ int main(int argc, char** argv)
154 154
 							l->type, l->class, l->ttl);
155 155
 					printf("       prio= %d weight=%d port=%d\n",
156 156
 								srv->priority, srv->weight, srv->port);
157
-					printf("       name= [%s]\n", srv->name);
157
+					printf("       name_len= %d (%d), name= [%.*s]\n",
158
+									srv->name_len, strlen(srv->name),
159
+									srv->name_len, srv->name);
158 160
 					break;
159 161
 				case T_CNAME:
160 162
 					printf("CNAME  type= %d class=%d  ttl=%d\n",
... ...
@@ -170,13 +181,32 @@ int main(int argc, char** argv)
170 170
 								ip->ip[0], ip->ip[1], ip->ip[2], ip->ip[3]);
171 171
 					break;
172 172
 				case T_AAAA:
173
-					printf("AAAA    type= %d class=%d  ttl=%d\n",
173
+					printf("AAAA   type= %d class=%d  ttl=%d\n",
174 174
 							l->type, l->class, l->ttl);
175 175
 					printf("        ip6= ");
176 176
 					for(r=0;r<16;r++) 
177 177
 						printf("%x ", ((struct aaaa_rdata*)l->rdata)->ip6[r]);
178 178
 					printf("\n");
179 179
 					break;
180
+				case T_NAPTR:
181
+					naptr=(struct naptr_rdata*)l->rdata;
182
+					printf("NAPTR  type= %d class=%d  ttl=%d\n",
183
+							l->type, l->class, l->ttl);
184
+					printf("       order= %d pref=%d\n",
185
+								naptr->order, naptr->pref);
186
+					printf("       flags_len= %d,     flags= [%.*s]\n",
187
+									naptr->flags_len, 
188
+									naptr->flags_len, naptr->flags);
189
+					printf("       services_len= %d,  services= [%.*s]\n",
190
+									naptr->services_len, 
191
+									naptr->services_len, naptr->services);
192
+					printf("       regexp_len= %d,    regexp= [%.*s]\n",
193
+									naptr->regexp_len, 
194
+									naptr->regexp_len, naptr->regexp);
195
+					printf("       repl_len= %d,      repl= [%s]\n",
196
+									naptr->repl_len, naptr->repl);
197
+					break;
198
+
180 199
 				default:
181 200
 					printf("UNKN    type= %d class=%d  ttl=%d\n",
182 201
 								l->type, l->class, l->ttl);