summaryrefslogtreecommitdiff
path: root/src/htslib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/htslib.c')
-rw-r--r--src/htslib.c243
1 files changed, 82 insertions, 161 deletions
diff --git a/src/htslib.c b/src/htslib.c
index fdd080e..886d8e3 100644
--- a/src/htslib.c
+++ b/src/htslib.c
@@ -2126,27 +2126,16 @@ htsblk http_test(httrackp * opt, char *adr, char *fil, char *loc) {
// peut ouvrir avec des connect() non bloquants: waitconnect=0/1
T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
int waitconnect) {
- t_fullhostent fullhostent_buffer; // buffer pour resolver
T_SOC soc; // descipteur de la socket
- char *iadr;
- // unsigned short int port;
-
- // si iadr="#" alors c'est une fausse URL, mais un vrai fichier
- // local.
- // utile pour les tests!
- //## if (iadr[0]!=lOCAL_CHAR) {
if (strcmp(_iadr, "file://") != 0) { /* non fichier */
SOCaddr server;
- int server_size = sizeof(server);
- t_hostent *hp;
const char *error = "unknown error";
- // effacer structure
- memset(&server, 0, sizeof(server));
-
// tester un éventuel id:pass et virer id:pass@ si détecté
- iadr = jump_identification(_iadr);
+ const char *const iadr = jump_identification(_iadr);
+
+ SOCaddr_clear(server);
#if HDEBUG
printf("gethostbyname\n");
@@ -2164,7 +2153,8 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
#else
port = 80; // port par défaut
#endif
- if (a) {
+
+ if (a != NULL) {
char BIGSTK iadr2[HTS_URLMAXSIZE * 2];
int i = -1;
@@ -2173,25 +2163,24 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
if (i != -1) {
port = (unsigned short int) i;
}
+
// adresse véritable (sans :xx)
strncatbuff(iadr2, iadr, (int) (a - iadr));
// adresse sans le :xx
- hp = hts_gethostbyname2(opt, iadr2, &fullhostent_buffer, &error);
+ hts_dns_resolve2(opt, iadr2, &server, &error);
} else {
// adresse normale (port par défaut par la suite)
- hp = hts_gethostbyname2(opt, iadr, &fullhostent_buffer, &error);
+ hts_dns_resolve2(opt, iadr, &server, &error);
}
- } else // port défini
- hp = hts_gethostbyname2(opt, iadr, &fullhostent_buffer, &error);
+ } else { // port défini
+ hts_dns_resolve2(opt, iadr, &server, &error);
+ }
- // Conversion iadr -> adresse
- // structure recevant le nom de l'hôte, etc
- //struct hostent *hp;
- if (hp == NULL) {
+ if (!SOCaddr_is_valid(server)) {
#if DEBUG
printf("erreur gethostbyname\n");
#endif
@@ -2206,13 +2195,10 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
}
return INVALID_SOCKET;
}
- // copie adresse
- SOCaddr_copyaddr(server, server_size, hp->h_addr_list[0], hp->h_length);
+
// make a copy for external clients
- retour->address_size = sizeof(retour->address);
- SOCaddr_copyaddr(retour->address, retour->address_size, hp->h_addr_list[0],
- hp->h_length);
- // memcpy(&SOCaddr_sinaddr(server), hp->h_addr_list[0], hp->h_length);
+ SOCaddr_copy_SOCaddr(retour->address, server);
+ retour->address_size = SOCaddr_size(retour->address);
// créer ("attachement") une socket (point d'accès) internet,en flot
#if HDEBUG
@@ -2246,14 +2232,13 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
}
// bind this address
if (retour != NULL && strnotempty(retour->req.proxy.bindhost)) {
- t_fullhostent bind_buffer;
const char *error = "unknown error";
+ SOCaddr bind_addr;
- hp = hts_gethostbyname2(opt, retour->req.proxy.bindhost, &bind_buffer,
- &error);
- if (hp == NULL
- || bind(soc, (struct sockaddr *) hp->h_addr_list[0],
- hp->h_length) != 0) {
+ if (hts_dns_resolve2(opt, retour->req.proxy.bindhost,
+ &bind_addr, &error) == NULL
+ || bind(soc, &SOCaddr_sockaddr(bind_addr),
+ SOCaddr_size(bind_addr)) != 0) {
if (retour && retour->msg) {
#ifdef _WIN32
snprintf(retour->msg, sizeof(retour->msg),
@@ -2305,25 +2290,20 @@ T_SOC newhttp(httrackp * opt, const char *_iadr, htsblk * retour, int port,
#if HTS_WIDE_DEBUG
DEBUG_W("connect\n");
#endif
-#ifdef _WIN32
- if (connect(soc, (const struct sockaddr FAR *) &server, server_size) != 0) {
-#else
- if (connect(soc, (struct sockaddr *) &server, server_size) == -1) {
-#endif
-
+ if (connect(soc, &SOCaddr_sockaddr(server), SOCaddr_size(server)) != 0) {
// bloquant
if (waitconnect) {
#if HDEBUG
printf("unable to connect!\n");
#endif
- if (retour && retour->msg) {
+ if (retour != NULL && retour->msg) {
#ifdef _WIN32
- int last_errno = WSAGetLastError();
+ const int last_errno = WSAGetLastError();
sprintf(retour->msg, "Unable to connect to the server: %s",
strerror(last_errno));
#else
- int last_errno = errno;
+ const int last_errno = errno;
sprintf(retour->msg, "Unable to connect to the server: %s",
strerror(last_errno));
@@ -2991,7 +2971,7 @@ int sendc(htsblk * r, const char *s) {
}
// Remplace read
-int finput(int fd, char *s, int max) {
+int finput(T_SOC fd, char *s, int max) {
char c;
int j = 0;
@@ -4568,7 +4548,6 @@ int hts_read(htsblk * r, char *buff, int size) {
// -- Gestion cache DNS --
// 'RX98
-#if HTS_DNSCACHE
// 'capsule' contenant uniquement le cache
t_dnscache *_hts_cache(httrackp * opt) {
@@ -4602,63 +4581,47 @@ void hts_cache_free(t_dnscache *const root) {
// routine pour le cache - retour optionnel à donner à chaque fois
// NULL: nom non encore testé dans le cache
// si h_length==0 alors le nom n'existe pas dans le dns
-static t_hostent *hts_ghbn(const t_dnscache *cache, const char *const iadr, t_hostent *retour) {
+static SOCaddr* hts_ghbn(const t_dnscache *cache, const char *const iadr, SOCaddr *const addr) {
+ assertf(addr != NULL);
for(; cache != NULL; cache = cache->n) {
assertf(cache != NULL);
assertf(iadr != NULL);
if (cache->iadr != NULL && strcmp(cache->iadr, iadr) == 0) { // ok trouvé
if (cache->host_length > 0) { // entrée valide
- if (retour->h_addr_list[0])
- memcpy(retour->h_addr_list[0], cache->host_addr, cache->host_length);
- retour->h_length = cache->host_length;
+ SOCaddr_copyaddr2(*addr, cache->host_addr, cache->host_length);
+ return addr;
} else if (cache->host_length == 0) { // en cours
return NULL;
} else { // erreur dans le dns, déja vérifié
- if (retour->h_addr_list[0])
- retour->h_addr_list[0][0] = '\0';
- retour->h_length = 0; // erreur, n'existe pas
+ SOCaddr_clear(*addr);
+ return addr;
}
- return retour;
}
}
return NULL;
}
-static t_hostent *vxgethostbyname2_(const char *const hostname,
- void *const v_buffer, const char **error) {
- t_fullhostent *buffer = (t_fullhostent *) v_buffer;
-
- /* Clear */
- fullhostent_init(buffer);
-
+static SOCaddr* hts_dns_resolve_nocache2_(const char *const hostname,
+ SOCaddr *const addr,
+ const char **error) {
{
#if HTS_INET6==0
- /*
- ipV4 resolver
- */
- t_hostent *hp = gethostbyname(hostname);
+ /* IPv4 resolver */
+ struct hostent *const hp = gethostbyname(hostname);
if (hp != NULL) {
- if ((hp->h_length)
- && (((unsigned int) hp->h_length) <= buffer->addr_maxlen)) {
- memcpy(buffer->hp.h_addr_list[0], hp->h_addr_list[0], hp->h_length);
- buffer->hp.h_length = hp->h_length;
- return &(buffer->hp);
- }
+ SOCaddr_copyaddr2(addr, hp->h_addr_list[0], hp->h_length);
+ return SOCaddr_is_valid(addr) ? &addr : NULL;
+ } else {
+ SOCaddr_clear(*addr);
}
#else
- /*
- ipV6 resolver
- */
- /*
- int error_num=0;
- t_hostent* hp=getipnodebyname(hostname, AF_INET6, AI_DEFAULT, &error_num);
- oops, deprecated :(
- */
+ /* IPv6 resolver */
struct addrinfo *res = NULL;
struct addrinfo hints;
int gerr;
+ SOCaddr_clear(*addr);
memset(&hints, 0, sizeof(hints));
if (IPV6_resolver == 1) // V4 only (for bogus V6 entries)
hints.ai_family = PF_INET;
@@ -4669,13 +4632,9 @@ static t_hostent *vxgethostbyname2_(const char *const hostname,
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if ( ( gerr = getaddrinfo(hostname, NULL, &hints, &res) ) == 0) {
- if (res) {
- if ((res->ai_addr) && (res->ai_addrlen)
- && (res->ai_addrlen <= buffer->addr_maxlen)) {
- memcpy(buffer->hp.h_addr_list[0], res->ai_addr, res->ai_addrlen);
- buffer->hp.h_length = (short) res->ai_addrlen;
- freeaddrinfo(res);
- return &(buffer->hp);
+ if (res != NULL) {
+ if (res->ai_addr != NULL && res->ai_addrlen != 0) {
+ SOCaddr_copyaddr2(*addr, res->ai_addr, res->ai_addrlen);
}
}
} else {
@@ -4688,11 +4647,12 @@ static t_hostent *vxgethostbyname2_(const char *const hostname,
}
#endif
}
- return NULL;
+
+ return SOCaddr_is_valid(*addr) ? addr : NULL;
}
-HTSEXT_API t_hostent *vxgethostbyname2(const char *const hostname,
- void *const v_buffer, const char **error) {
+HTSEXT_API SOCaddr* hts_dns_resolve_nocache2(const char *const hostname,
+ SOCaddr *const addr, const char **error) {
/* Protection */
if (!strnotempty(hostname)) {
return NULL;
@@ -4703,43 +4663,40 @@ HTSEXT_API t_hostent *vxgethostbyname2(const char *const hostname,
The resolver doesn't seem to handle IP6 addresses in brackets
*/
if ((hostname[0] == '[') && (hostname[strlen(hostname) - 1] == ']')) {
- t_hostent *ret;
+ SOCaddr *ret;
size_t size = strlen(hostname);
char *copy = malloct(size + 1);
assertf(copy != NULL);
copy[0] = '\0';
strncat(copy, hostname + 1, size - 2);
- ret = vxgethostbyname2_(copy, v_buffer, error);
+ ret = hts_dns_resolve_nocache2_(copy, addr, error);
freet(copy);
return ret;
} else {
- return vxgethostbyname2_(hostname, v_buffer, error);
+ return hts_dns_resolve_nocache2_(hostname, addr, error);
}
}
-HTSEXT_API t_hostent *vxgethostbyname(const char *const hostname, void *v_buffer) {
- return vxgethostbyname2(hostname, v_buffer, NULL);
+HTSEXT_API SOCaddr* hts_dns_resolve_nocache(const char *const hostname, SOCaddr *const addr) {
+ return hts_dns_resolve_nocache2(hostname, addr, NULL);
}
HTSEXT_API int check_hostname_dns(const char *const hostname) {
- t_fullhostent buffer;
- return vxgethostbyname(hostname, &buffer) != NULL;
+ SOCaddr buffer;
+ return hts_dns_resolve_nocache(hostname, &buffer) != NULL;
}
// Needs locking
// cache dns interne à HTS // ** FREE A FAIRE sur la chaine
-static t_hostent *hts_gethostbyname_(httrackp * opt, const char *_iadr, void *v_buffer, const char **error) {
+static SOCaddr* hts_dns_resolve_(httrackp * opt, const char *_iadr,
+ SOCaddr *const addr, const char **error) {
char BIGSTK iadr[HTS_URLMAXSIZE * 2];
- t_fullhostent *buffer = (t_fullhostent *) v_buffer;
t_dnscache *cache = _hts_cache(opt); // adresse du cache
- t_hostent *hp;
+ SOCaddr *sa;
assertf(opt != NULL);
assertf(_iadr != NULL);
- assertf(v_buffer != NULL);
-
- /* Clear */
- fullhostent_init(buffer);
+ assertf(addr != NULL);
strcpybuff(iadr, jump_identification(_iadr));
// couper éventuel :
@@ -4751,91 +4708,55 @@ static t_hostent *hts_gethostbyname_(httrackp * opt, const char *_iadr, void *v_
}
/* get IP from the dns cache */
- hp = hts_ghbn(cache, iadr, &buffer->hp);
- if (hp) {
- if (hp->h_length > 0)
- return hp;
- else
- return NULL; // entrée erronée (erreur DNS) dans le DNS
+ sa = hts_ghbn(cache, iadr, addr);
+ if (sa != NULL) {
+ return SOCaddr_is_valid(*sa) ? sa : NULL;
} else { // non présent dans le cache dns, tester
// find queue
for(; cache->n != NULL; cache = cache->n) ;
-#if HTS_WIDE_DEBUG
- DEBUG_W("gethostbyname\n");
-#endif
-#if HDEBUG
- printf("gethostbyname (not in cache)\n");
-#endif
- {
- unsigned long inetaddr;
-
-#ifdef _WIN32
- if ((inetaddr = inet_addr(iadr)) == INADDR_NONE) {
-#else
- if ((inetaddr = inet_addr(iadr)) == (in_addr_t) - 1) {
-#endif
#if DEBUGDNS
- printf("resolving (not cached) %s\n", iadr);
+ printf("resolving (not cached) %s\n", iadr);
#endif
- hp = vxgethostbyname2(iadr, buffer, error); // calculer IP host
- } else { // numérique, convertir sans passer par le dns
- buffer->hp.h_addr_list[0] = (char *) &inetaddr;
- buffer->hp.h_length = 4;
- hp = &buffer->hp;
- }
- }
+
+ sa = hts_dns_resolve_nocache2(iadr, addr, error); // calculer IP host
+
#if HTS_WIDE_DEBUG
DEBUG_W("gethostbyname done\n");
#endif
+
+ /* attempt to store new entry */
cache->n = (t_dnscache *) calloct(1, sizeof(t_dnscache));
if (cache->n != NULL) {
strcpybuff(cache->n->iadr, iadr);
- if (hp != NULL) {
- memcpy(cache->n->host_addr, hp->h_addr_list[0], hp->h_length);
- cache->n->host_length = hp->h_length;
+ if (sa != NULL) {
+ cache->n->host_length = SOCaddr_size(*sa);
+ assertf(cache->n->host_length < sizeof(cache->n->host_addr));
+ memcpy(cache->n->host_addr, &SOCaddr_sockaddr(*sa), cache->n->host_length);
} else {
cache->n->host_addr[0] = '\0';
cache->n->host_length = 0; // non existant dans le dns
}
cache->n->n = NULL;
- return hp;
- } else { // on peut pas noter, mais on peut renvoyer le résultat
- return hp;
+ return sa;
}
+
+ /* return result if any */
+ return sa;
} // retour hp du cache
}
-t_hostent *hts_gethostbyname2(httrackp * opt, const char *_iadr, void *v_buffer, const char **error) {
- t_hostent *ret;
+SOCaddr* hts_dns_resolve2(httrackp * opt, const char *_iadr, SOCaddr *const addr, const char **error) {
+ SOCaddr *ret;
hts_mutexlock(&opt->state.lock);
- ret = hts_gethostbyname_(opt, _iadr, v_buffer, error);
+ ret = hts_dns_resolve_(opt, _iadr, addr, error);
hts_mutexrelease(&opt->state.lock);
return ret;
}
-t_hostent *hts_gethostbyname(httrackp * opt, const char *_iadr, void *v_buffer) {
- return hts_gethostbyname2(opt ,_iadr, v_buffer, NULL);
-}
-
-#else
-static HTS_INLINE t_hostent *hts_gethostbyname(httrackp * opt, char *iadr,
- t_fullhostent * buffer) {
- t_hostent *retour;
-
-#if HTS_WIDE_DEBUG
- DEBUG_W("gethostbyname (2)\n");
-#endif
-#if DEBUGDNS
- printf("blocking method gethostbyname() in progress for %s\n", iadr);
-#endif
- retour = vxgethostbyname(jump_identification(iadr),);
-#if HTS_WIDE_DEBUG
- DEBUG_W("gethostbyname (2) done\n");
-#endif
- return retour;
+SOCaddr* hts_dns_resolve(httrackp * opt, const char *_iadr, SOCaddr *const addr) {
+ return hts_dns_resolve2(opt, _iadr, addr, NULL);
}
-#endif
// --- Tracage des mallocs() ---
#ifdef HTS_TRACE_MALLOC