Rewrite sock lib to not use malloc.

This commit is contained in:
James Canete
2008-07-03 00:26:44 +00:00
parent 9c49b16554
commit 1c098531d8

View File

@@ -209,29 +209,30 @@ struct dnsquery_header
struct dnsquery_question
{
char *qname;
char qname[1024];
unsigned short qtype;
unsigned short qclass;
};
struct dnsquery_resourcerecord
{
char *name;
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short rdlength;
void *rdata;
};
struct dnsquery_srvrdata
{
unsigned short priority;
unsigned short weight;
unsigned short port;
char *target;
char target[1024];
};
struct dnsquery_resourcerecord
{
char name[1024];
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short rdlength;
struct dnsquery_srvrdata rdata;
};
void netbuf_add_32bitnum(unsigned char *buf, int buflen, int *offset, unsigned int num)
{
unsigned char *start = buf + *offset;
@@ -327,34 +328,6 @@ void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset,
*p++ = '\0';
*offset += p - start;
#if 0
unsigned char *start = buf + *offset;
unsigned char *p = start;
while (*labellist)
{
int len = strlen(*labellist);
char *p2 = *labellist;
if (len > 0x3F)
{
len = 0x3F;
}
*p++ = len & 0xFF;
while (len)
{
*p++ = *p2++;
len--;
}
labellist++;
}
*p++ = '\0';
*offset += p - start;
#endif
}
int calc_domain_name_size(unsigned char *buf, int buflen, int offset)
@@ -386,15 +359,42 @@ int calc_domain_name_size(unsigned char *buf, int buflen, int offset)
return len;
}
void netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char **name)
int netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char *namebuf, int namebuflen)
{
unsigned char *start = buf + *offset;
unsigned char *p = start;
unsigned char *p, *p2;
int *curroffset = offset;
int len = 0;
*name = malloc(sizeof(**name) * (calc_domain_name_size(buf, buflen, *offset) + 1));
**name = '\0';
*namebuf = '\0';
/* measure length */
p = start;
while (*p)
{
if ((*p & 0xC0) == 0xC0)
{
int newoffset = 0;
newoffset |= (*p++ & 0x3F) << 8;
newoffset |= *p++;
p = buf + newoffset;
}
else
{
len += *p;
p += *p + 1;
}
}
if (namebuflen < len)
{
return len;
}
/* actually copy in name */
p = start;
p2 = namebuf;
while (*p)
{
if ((*p & 0xC0) == 0xC0)
@@ -413,13 +413,19 @@ void netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char **
}
else
{
if (**name != '\0')
int i, partlen;
if (*namebuf != '\0')
{
strcat(*name, ".");
*p2++ = '.';
}
strncat(*name, (char *)p + 1, *p);
p += *p + 1;
partlen = *p++;
for (i=0; i < partlen; i++)
{
*p2++ = *p++;
}
}
}
@@ -430,77 +436,9 @@ void netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char **
curroffset = NULL;
}
#if 0
unsigned char *start = buf + *offset;
unsigned char *p = start;
char **labelp;
int numlabels = 1;
int tracking = 1;
*p2 = '\0';
/* check if this is a reference */
if ((*p & 0xC0) == 0xC0)
{
/* it is, parse the old reference */
int newoffset = 0;
newoffset |= (*p++ & 0x3F) << 8;
newoffset |= (*p++);
netbuf_get_label_list(buf, buflen, &newoffset, labellist);
*offset += 2;
return;
}
/* count the number of labels we need */
while (*p && )
{
if ((*p & 0xC0) == 0xC0)
{
p += 2;
}
else
{
p += *p;
}
numlabels++;
}
*labellist = malloc(sizeof(**labellist) + 1);
labelp = *labellist;
p = start;
while (*p)
{
if ((*p & 0xC0) == 0xC0)
{
}
else
{
int len = *p++;
unsigned char *p2;
*labelp = malloc(len + 1);
p2 = *labelp;
while (len)
{
*p2++ = *p++;
len--;
}
*p2++ = '\0';
labelp++;
}
}
*labelp = NULL;
p++;
*offset += p - start;
#endif
return 0;
}
void netbuf_add_dnsquery_header(unsigned char *buf, int buflen, int *offset, struct dnsquery_header *header)
@@ -553,7 +491,6 @@ void netbuf_get_dnsquery_header(unsigned char *buf, int buflen, int *offset, str
void netbuf_add_dnsquery_question(unsigned char *buf, int buflen, int *offset, struct dnsquery_question *question)
{
/*netbuf_add_label_list(buf, buflen, offset, question->qname);*/
netbuf_add_domain_name(buf, buflen, offset, question->qname);
netbuf_add_16bitnum(buf, buflen, offset, question->qtype);
netbuf_add_16bitnum(buf, buflen, offset, question->qclass);
@@ -561,8 +498,7 @@ void netbuf_add_dnsquery_question(unsigned char *buf, int buflen, int *offset, s
void netbuf_get_dnsquery_question(unsigned char *buf, int buflen, int *offset, struct dnsquery_question *question)
{
/*netbuf_get_label_list(buf, buflen, offset, &(question->qname));*/
netbuf_get_domain_name(buf, buflen, offset, &(question->qname));
netbuf_get_domain_name(buf, buflen, offset, question->qname, 1024);
netbuf_get_16bitnum(buf, buflen, offset, &(question->qtype));
netbuf_get_16bitnum(buf, buflen, offset, &(question->qclass));
}
@@ -572,13 +508,12 @@ void netbuf_get_dnsquery_srvrdata(unsigned char *buf, int buflen, int *offset, s
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->priority));
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->weight));
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->port));
netbuf_get_domain_name(buf, buflen, offset, &(srvrdata->target));
netbuf_get_domain_name(buf, buflen, offset, srvrdata->target, 1024);
}
void netbuf_get_dnsquery_resourcerecord(unsigned char *buf, int buflen, int *offset, struct dnsquery_resourcerecord *rr)
{
/*netbuf_get_label_list(buf, buflen, offset, &(rr->name));*/
netbuf_get_domain_name(buf, buflen, offset, &(rr->name));
netbuf_get_domain_name(buf, buflen, offset, rr->name, 1024);
netbuf_get_16bitnum(buf, buflen, offset, &(rr->type));
netbuf_get_16bitnum(buf, buflen, offset, &(rr->_class));
netbuf_get_32bitnum(buf, buflen, offset, &(rr->ttl));
@@ -586,68 +521,11 @@ void netbuf_get_dnsquery_resourcerecord(unsigned char *buf, int buflen, int *off
if (rr->type == 33) /* SRV */
{
int newoffset = *offset;
rr->rdata = malloc(sizeof(struct dnsquery_srvrdata));
netbuf_get_dnsquery_srvrdata(buf, buflen, &newoffset, rr->rdata);
}
else
{
rr->rdata = buf + *offset;
netbuf_get_dnsquery_srvrdata(buf, buflen, &newoffset, &(rr->rdata));
}
*offset += rr->rdlength;
}
char **SeparateStringByDots(char *string)
{
char **result;
char *p = string;
char **ps;
int numstrings = 1;
while (*p)
{
if (*p++ == '.')
{
numstrings++;
}
}
p = string;
result = malloc(sizeof(*result) * numstrings);
ps = result;
while (*p)
{
char *p2 = p;
while (*p2 && *p2 != '.')
{
p2++;
}
*ps = malloc(sizeof(*ps) * ((int)(p2 - p) + 1));
p2 = *ps;
while (*p && *p != '.')
{
*p2++ = *p++;
}
*p2 = '\0';
ps++;
if (*p == '.')
{
p++;
}
}
*ps = NULL;
return result;
}
int sock_srv_lookup(const char *service, const char *proto, const char *domain, char *resulttarget, int resulttargetlength, int *resultport)
{
@@ -662,8 +540,8 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
{
HINSTANCE hdnsapi = NULL;
DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, PDNS_RECORD*, PVOID*);
void (WINAPI * pDnsRecordListFree)(PDNS_RECORD, DNS_FREE_TYPE);
DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, PDNS_RECORD*, PVOID*);
void (WINAPI * pDnsRecordListFree)(PDNS_RECORD, DNS_FREE_TYPE);
if (hdnsapi = LoadLibrary("dnsapi.dll")) {
@@ -705,20 +583,19 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
unsigned char buf[65536];
struct dnsquery_header header;
struct dnsquery_question question;
unsigned char *p, **qname;
int offset = 0;
int addrlen;
sock_t sock;
struct sockaddr_in dnsaddr;
char dnsserverips[16][256];
int numdnsservers = 0;
int i, j;
int j;
/* Try getting the DNS server ips from GetNetworkParams() in iphlpapi first */
if (!numdnsservers)
{
HINSTANCE hiphlpapi = NULL;
DWORD (WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
HINSTANCE hiphlpapi = NULL;
DWORD (WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
if (hiphlpapi = LoadLibrary("Iphlpapi.dll"))
{
@@ -729,23 +606,20 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
FIXED_INFO *fi;
ULONG len;
DWORD error;
len = 0;
char buffer[65535];
/* get the size and malloc it */
if ((error = pGetNetworkParams(NULL, &len)) == ERROR_BUFFER_OVERFLOW)
len = 65535;
fi = buffer;
if ((error = pGetNetworkParams(fi, &len)) == ERROR_SUCCESS)
{
fi = malloc(len);
if ((error = pGetNetworkParams(fi, &len)) == ERROR_SUCCESS)
{
IP_ADDR_STRING *pias = &(fi->DnsServerList);
IP_ADDR_STRING *pias = &(fi->DnsServerList);
while (pias && numdnsservers < 16)
{
strcpy(dnsserverips[numdnsservers++], pias->IpAddress.String);
pias = pias->Next;
}
while (pias && numdnsservers < 16)
{
strcpy(dnsserverips[numdnsservers++], pias->IpAddress.String);
pias = pias->Next;
}
free(fi);
}
}
}
@@ -815,7 +689,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
if (error == ERROR_SUCCESS)
{
int i;
unsigned int i;
DWORD numinterfaces = 0;
RegQueryInfoKey(searchlist, NULL, NULL, NULL, &numinterfaces, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -900,7 +774,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
netbuf_add_dnsquery_header(buf, 65536, &offset, &header);
memset(&question, 0, sizeof(question));
question.qname = fulldomain;
strncpy(question.qname, fulldomain, 1024);
question.qtype = 33; /* SRV */
question.qclass = 1; /* INTERNET! */
@@ -914,8 +788,8 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
memset(&dnsaddr, 0, sizeof(dnsaddr));
dnsaddr.sin_family = AF_INET;
dnsaddr.sin_port = htons(53);
dnsaddr.sin_family = AF_INET;
dnsaddr.sin_port = htons(53);
dnsaddr.sin_addr.s_addr = inet_addr(dnsserverips[i]);
addrlen = sizeof(dnsaddr);
@@ -967,7 +841,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
if (rr.type == 33)
{
struct dnsquery_srvrdata *srvrdata = rr.rdata;
struct dnsquery_srvrdata *srvrdata = &(rr.rdata);
snprintf(resulttarget, resulttargetlength, srvrdata->target);
*resultport = srvrdata->port;