Rewrite sock lib to not use malloc.
This commit is contained in:
286
src/sock.c
286
src/sock.c
@@ -209,29 +209,30 @@ struct dnsquery_header
|
|||||||
|
|
||||||
struct dnsquery_question
|
struct dnsquery_question
|
||||||
{
|
{
|
||||||
char *qname;
|
char qname[1024];
|
||||||
unsigned short qtype;
|
unsigned short qtype;
|
||||||
unsigned short qclass;
|
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
|
struct dnsquery_srvrdata
|
||||||
{
|
{
|
||||||
unsigned short priority;
|
unsigned short priority;
|
||||||
unsigned short weight;
|
unsigned short weight;
|
||||||
unsigned short port;
|
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)
|
void netbuf_add_32bitnum(unsigned char *buf, int buflen, int *offset, unsigned int num)
|
||||||
{
|
{
|
||||||
unsigned char *start = buf + *offset;
|
unsigned char *start = buf + *offset;
|
||||||
@@ -327,34 +328,6 @@ void netbuf_add_domain_name(unsigned char *buf, int buflen, int *offset,
|
|||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
*offset += p - start;
|
*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)
|
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;
|
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 *start = buf + *offset;
|
||||||
unsigned char *p = start;
|
unsigned char *p, *p2;
|
||||||
int *curroffset = offset;
|
int *curroffset = offset;
|
||||||
|
int len = 0;
|
||||||
|
|
||||||
*name = malloc(sizeof(**name) * (calc_domain_name_size(buf, buflen, *offset) + 1));
|
*namebuf = '\0';
|
||||||
**name = '\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)
|
while (*p)
|
||||||
{
|
{
|
||||||
if ((*p & 0xC0) == 0xC0)
|
if ((*p & 0xC0) == 0xC0)
|
||||||
@@ -413,13 +413,19 @@ void netbuf_get_domain_name(unsigned char *buf, int buflen, int *offset, char **
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (**name != '\0')
|
int i, partlen;
|
||||||
|
|
||||||
|
if (*namebuf != '\0')
|
||||||
{
|
{
|
||||||
strcat(*name, ".");
|
*p2++ = '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
strncat(*name, (char *)p + 1, *p);
|
partlen = *p++;
|
||||||
p += *p + 1;
|
|
||||||
|
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;
|
curroffset = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
*p2 = '\0';
|
||||||
unsigned char *start = buf + *offset;
|
|
||||||
unsigned char *p = start;
|
|
||||||
char **labelp;
|
|
||||||
int numlabels = 1;
|
|
||||||
int tracking = 1;
|
|
||||||
|
|
||||||
/* check if this is a reference */
|
return 0;
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void netbuf_add_dnsquery_header(unsigned char *buf, int buflen, int *offset, struct dnsquery_header *header)
|
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)
|
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_domain_name(buf, buflen, offset, question->qname);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, question->qtype);
|
netbuf_add_16bitnum(buf, buflen, offset, question->qtype);
|
||||||
netbuf_add_16bitnum(buf, buflen, offset, question->qclass);
|
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)
|
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, 1024);
|
||||||
netbuf_get_domain_name(buf, buflen, offset, &(question->qname));
|
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(question->qtype));
|
netbuf_get_16bitnum(buf, buflen, offset, &(question->qtype));
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(question->qclass));
|
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->priority));
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->weight));
|
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->weight));
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(srvrdata->port));
|
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)
|
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, 1024);
|
||||||
netbuf_get_domain_name(buf, buflen, offset, &(rr->name));
|
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(rr->type));
|
netbuf_get_16bitnum(buf, buflen, offset, &(rr->type));
|
||||||
netbuf_get_16bitnum(buf, buflen, offset, &(rr->_class));
|
netbuf_get_16bitnum(buf, buflen, offset, &(rr->_class));
|
||||||
netbuf_get_32bitnum(buf, buflen, offset, &(rr->ttl));
|
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 */
|
if (rr->type == 33) /* SRV */
|
||||||
{
|
{
|
||||||
int newoffset = *offset;
|
int newoffset = *offset;
|
||||||
rr->rdata = malloc(sizeof(struct dnsquery_srvrdata));
|
netbuf_get_dnsquery_srvrdata(buf, buflen, &newoffset, &(rr->rdata));
|
||||||
netbuf_get_dnsquery_srvrdata(buf, buflen, &newoffset, rr->rdata);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rr->rdata = buf + *offset;
|
|
||||||
}
|
}
|
||||||
*offset += rr->rdlength;
|
*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)
|
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;
|
HINSTANCE hdnsapi = NULL;
|
||||||
|
|
||||||
DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, PDNS_RECORD*, PVOID*);
|
DNS_STATUS (WINAPI * pDnsQuery_A)(PCSTR, WORD, DWORD, PIP4_ARRAY, PDNS_RECORD*, PVOID*);
|
||||||
void (WINAPI * pDnsRecordListFree)(PDNS_RECORD, DNS_FREE_TYPE);
|
void (WINAPI * pDnsRecordListFree)(PDNS_RECORD, DNS_FREE_TYPE);
|
||||||
|
|
||||||
if (hdnsapi = LoadLibrary("dnsapi.dll")) {
|
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];
|
unsigned char buf[65536];
|
||||||
struct dnsquery_header header;
|
struct dnsquery_header header;
|
||||||
struct dnsquery_question question;
|
struct dnsquery_question question;
|
||||||
unsigned char *p, **qname;
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int addrlen;
|
int addrlen;
|
||||||
sock_t sock;
|
sock_t sock;
|
||||||
struct sockaddr_in dnsaddr;
|
struct sockaddr_in dnsaddr;
|
||||||
char dnsserverips[16][256];
|
char dnsserverips[16][256];
|
||||||
int numdnsservers = 0;
|
int numdnsservers = 0;
|
||||||
int i, j;
|
int j;
|
||||||
|
|
||||||
/* Try getting the DNS server ips from GetNetworkParams() in iphlpapi first */
|
/* Try getting the DNS server ips from GetNetworkParams() in iphlpapi first */
|
||||||
if (!numdnsservers)
|
if (!numdnsservers)
|
||||||
{
|
{
|
||||||
HINSTANCE hiphlpapi = NULL;
|
HINSTANCE hiphlpapi = NULL;
|
||||||
DWORD (WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
|
DWORD (WINAPI * pGetNetworkParams)(PFIXED_INFO, PULONG);
|
||||||
|
|
||||||
if (hiphlpapi = LoadLibrary("Iphlpapi.dll"))
|
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;
|
FIXED_INFO *fi;
|
||||||
ULONG len;
|
ULONG len;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
len = 0;
|
char buffer[65535];
|
||||||
|
|
||||||
/* get the size and malloc it */
|
len = 65535;
|
||||||
if ((error = pGetNetworkParams(NULL, &len)) == ERROR_BUFFER_OVERFLOW)
|
fi = buffer;
|
||||||
|
|
||||||
|
if ((error = pGetNetworkParams(fi, &len)) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
fi = malloc(len);
|
IP_ADDR_STRING *pias = &(fi->DnsServerList);
|
||||||
if ((error = pGetNetworkParams(fi, &len)) == ERROR_SUCCESS)
|
|
||||||
{
|
|
||||||
IP_ADDR_STRING *pias = &(fi->DnsServerList);
|
|
||||||
|
|
||||||
while (pias && numdnsservers < 16)
|
while (pias && numdnsservers < 16)
|
||||||
{
|
{
|
||||||
strcpy(dnsserverips[numdnsservers++], pias->IpAddress.String);
|
strcpy(dnsserverips[numdnsservers++], pias->IpAddress.String);
|
||||||
pias = pias->Next;
|
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)
|
if (error == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
int i;
|
unsigned int i;
|
||||||
DWORD numinterfaces = 0;
|
DWORD numinterfaces = 0;
|
||||||
|
|
||||||
RegQueryInfoKey(searchlist, NULL, NULL, NULL, &numinterfaces, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
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);
|
netbuf_add_dnsquery_header(buf, 65536, &offset, &header);
|
||||||
|
|
||||||
memset(&question, 0, sizeof(question));
|
memset(&question, 0, sizeof(question));
|
||||||
question.qname = fulldomain;
|
strncpy(question.qname, fulldomain, 1024);
|
||||||
question.qtype = 33; /* SRV */
|
question.qtype = 33; /* SRV */
|
||||||
question.qclass = 1; /* INTERNET! */
|
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));
|
memset(&dnsaddr, 0, sizeof(dnsaddr));
|
||||||
|
|
||||||
dnsaddr.sin_family = AF_INET;
|
dnsaddr.sin_family = AF_INET;
|
||||||
dnsaddr.sin_port = htons(53);
|
dnsaddr.sin_port = htons(53);
|
||||||
dnsaddr.sin_addr.s_addr = inet_addr(dnsserverips[i]);
|
dnsaddr.sin_addr.s_addr = inet_addr(dnsserverips[i]);
|
||||||
|
|
||||||
addrlen = sizeof(dnsaddr);
|
addrlen = sizeof(dnsaddr);
|
||||||
@@ -967,7 +841,7 @@ int sock_srv_lookup(const char *service, const char *proto, const char *domain,
|
|||||||
|
|
||||||
if (rr.type == 33)
|
if (rr.type == 33)
|
||||||
{
|
{
|
||||||
struct dnsquery_srvrdata *srvrdata = rr.rdata;
|
struct dnsquery_srvrdata *srvrdata = &(rr.rdata);
|
||||||
|
|
||||||
snprintf(resulttarget, resulttargetlength, srvrdata->target);
|
snprintf(resulttarget, resulttargetlength, srvrdata->target);
|
||||||
*resultport = srvrdata->port;
|
*resultport = srvrdata->port;
|
||||||
|
|||||||
Reference in New Issue
Block a user