85
85
*/
86
86
87
87
int ares_create_query (const char * name , int dnsclass , int type ,
88
- unsigned short id , int rd , unsigned char * * buf ,
89
- int * buflen , int max_udp_size )
88
+ unsigned short id , int rd , unsigned char * * bufp ,
89
+ int * buflenp , int max_udp_size )
90
90
{
91
- int len ;
91
+ size_t len ;
92
92
unsigned char * q ;
93
93
const char * p ;
94
+ size_t buflen ;
95
+ unsigned char * buf ;
94
96
95
97
/* Set our results early, in case we bail out early with an error. */
96
- * buflen = 0 ;
97
- * buf = NULL ;
98
+ * buflenp = 0 ;
99
+ * bufp = NULL ;
98
100
99
- /* Compute the length of the encoded name so we can check buflen.
100
- * Start counting at 1 for the zero-length label at the end. */
101
- len = 1 ;
102
- for (p = name ; * p ; p ++ )
103
- {
104
- if (* p == '\\' && * (p + 1 ) != 0 )
105
- p ++ ;
106
- len ++ ;
107
- }
108
- /* If there are n periods in the name, there are n + 1 labels, and
109
- * thus n + 1 length fields, unless the name is empty or ends with a
110
- * period. So add 1 unless name is empty or ends with a period.
101
+ /* Allocate a memory area for the maximum size this packet might need. +2
102
+ * is for the length byte and zero termination if no dots or ecscaping is
103
+ * used.
111
104
*/
112
- if (* name && * (p - 1 ) != '.' )
113
- len ++ ;
114
-
115
- /* Immediately reject names that are longer than the maximum of 255
116
- * bytes that's specified in RFC 1035 ("To simplify implementations,
117
- * the total length of a domain name (i.e., label octets and label
118
- * length octets) is restricted to 255 octets or less."). We aren't
119
- * doing this just to be a stickler about RFCs. For names that are
120
- * too long, 'dnscache' closes its TCP connection to us immediately
121
- * (when using TCP) and ignores the request when using UDP, and
122
- * BIND's named returns ServFail (TCP or UDP). Sending a request
123
- * that we know will cause 'dnscache' to close the TCP connection is
124
- * painful, since that makes any other outstanding requests on that
125
- * connection fail. And sending a UDP request that we know
126
- * 'dnscache' will ignore is bad because resources will be tied up
127
- * until we time-out the request.
128
- */
129
- if (len > MAXCDNAME )
130
- return ARES_EBADNAME ;
131
-
132
- * buflen = len + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0 );
133
- * buf = malloc (* buflen );
134
- if (!* buf )
135
- return ARES_ENOMEM ;
105
+ len = strlen (name ) + 2 + HFIXEDSZ + QFIXEDSZ +
106
+ (max_udp_size ? EDNSFIXEDSZ : 0 );
107
+ buf = malloc (len );
108
+ if (!buf )
109
+ return ARES_ENOMEM ;
136
110
137
111
/* Set up the header. */
138
- q = * buf ;
112
+ q = buf ;
139
113
memset (q , 0 , HFIXEDSZ );
140
114
DNS_HEADER_SET_QID (q , id );
141
115
DNS_HEADER_SET_OPCODE (q , QUERY );
@@ -159,8 +133,10 @@ int ares_create_query(const char *name, int dnsclass, int type,
159
133
q += HFIXEDSZ ;
160
134
while (* name )
161
135
{
162
- if (* name == '.' )
136
+ if (* name == '.' ) {
137
+ free (buf );
163
138
return ARES_EBADNAME ;
139
+ }
164
140
165
141
/* Count the number of bytes in this label. */
166
142
len = 0 ;
@@ -170,8 +146,10 @@ int ares_create_query(const char *name, int dnsclass, int type,
170
146
p ++ ;
171
147
len ++ ;
172
148
}
173
- if (len > MAXLABEL )
149
+ if (len > MAXLABEL ) {
150
+ free (buf );
174
151
return ARES_EBADNAME ;
152
+ }
175
153
176
154
/* Encode the length and copy the data. */
177
155
* q ++ = (unsigned char )len ;
@@ -195,14 +173,30 @@ int ares_create_query(const char *name, int dnsclass, int type,
195
173
DNS_QUESTION_SET_TYPE (q , type );
196
174
DNS_QUESTION_SET_CLASS (q , dnsclass );
197
175
176
+ q += QFIXEDSZ ;
198
177
if (max_udp_size )
199
178
{
200
- q += QFIXEDSZ ;
201
179
memset (q , 0 , EDNSFIXEDSZ );
202
180
q ++ ;
203
181
DNS_RR_SET_TYPE (q , T_OPT );
204
182
DNS_RR_SET_CLASS (q , max_udp_size );
183
+ q += (EDNSFIXEDSZ - 1 );
184
+ }
185
+ buflen = (q - buf );
186
+
187
+ /* Reject names that are longer than the maximum of 255 bytes that's
188
+ * specified in RFC 1035 ("To simplify implementations, the total length of
189
+ * a domain name (i.e., label octets and label length octets) is restricted
190
+ * to 255 octets or less."). */
191
+ if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
192
+ (max_udp_size ? EDNSFIXEDSZ : 0 ))) {
193
+ free (buf );
194
+ return ARES_EBADNAME ;
205
195
}
206
196
197
+ /* we know this fits in an int at this point */
198
+ * buflenp = (int ) buflen ;
199
+ * bufp = buf ;
200
+
207
201
return ARES_SUCCESS ;
208
202
}
0 commit comments