mirror of
https://gitea.invidious.io/iv-org/litespeed-quic.git
synced 2024-08-15 00:53:43 +00:00
DNS resolution: can specify hostname via -H or -s
This commit is contained in:
parent
f6b053a9b4
commit
07354a9a23
8 changed files with 144 additions and 121 deletions
|
@ -1,5 +1,6 @@
|
||||||
2018-05-16
|
2018-05-16
|
||||||
|
|
||||||
|
- [FEATURE] DNS resolution
|
||||||
- [BUGFIX] Frame insertion mis-ID as overlap instead of dup
|
- [BUGFIX] Frame insertion mis-ID as overlap instead of dup
|
||||||
- http_client: fix priority range generated by -E flag
|
- http_client: fix priority range generated by -E flag
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ to the LiteSpeed Client Library:
|
||||||
- Amol Desphande -- Windows support
|
- Amol Desphande -- Windows support
|
||||||
- Alexis La Goutte -- Travis-CI integration
|
- Alexis La Goutte -- Travis-CI integration
|
||||||
- Bernhard Jaeger -- DNS Resolution
|
- Bernhard Jaeger -- DNS Resolution
|
||||||
|
|
||||||
Thank you!
|
Thank you!
|
||||||
|
|
||||||
We welcome contributions in any form -- patches, issues, pull requests.
|
We welcome contributions in any form -- patches, issues, pull requests.
|
||||||
|
|
20
EXAMPLES.txt
20
EXAMPLES.txt
|
@ -9,21 +9,17 @@ Usage Examples
|
||||||
|
|
||||||
Fetch Google's home page:
|
Fetch Google's home page:
|
||||||
|
|
||||||
./http_client -H www.google.com -s 443 -p /
|
./http_client -s www.google.com -p /
|
||||||
|
|
||||||
In the example above, -H specifies the domain; it is also used as the value
|
The default port number is 443, but it can be specified after colon
|
||||||
of SNI paramater in the handshake.
|
using the -s flag. The value of the `host' header as well as the SNI
|
||||||
|
value defaults to the host part of the -s option. -H option can be
|
||||||
|
used to override it. For example:
|
||||||
|
|
||||||
The port number is specified using the -s flag.
|
./http_client -H www.youtube.com -s www.google.com:443 -p / -M HEAD
|
||||||
The ip adress is determined automatically.
|
|
||||||
The -6 flag tells the program to use IPv6 instead of IPv4.
|
|
||||||
Note that -6 must be used before -s in order to work.
|
|
||||||
|
|
||||||
You can also specify a certain ip-address with the -s command.
|
The host part can be an IP address. Both IPv4 and IPv6 are supported.
|
||||||
Note that this example won't work everywhere since google has a lot of different ips.
|
See ./http_client -h for a (long) list of different flags.
|
||||||
You have to look up the correct one for yourself.
|
|
||||||
|
|
||||||
./http_client -H www.google.com -s 172.217.22.4:443 -p /
|
|
||||||
|
|
||||||
POST a file to calculate its CRC32 checksum:
|
POST a file to calculate its CRC32 checksum:
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* http_client.c -- A simple HTTP/QUIC client
|
* http_client.c -- A simple HTTP/QUIC client
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -52,7 +53,6 @@ struct path_elem {
|
||||||
struct http_client_ctx {
|
struct http_client_ctx {
|
||||||
TAILQ_HEAD(, lsquic_conn_ctx)
|
TAILQ_HEAD(, lsquic_conn_ctx)
|
||||||
conn_ctxs;
|
conn_ctxs;
|
||||||
struct service_port *sport;
|
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
const char *method;
|
const char *method;
|
||||||
const char *payload;
|
const char *payload;
|
||||||
|
@ -158,6 +158,7 @@ struct lsquic_stream_ctx {
|
||||||
struct lsquic_reader reader;
|
struct lsquic_reader reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static lsquic_stream_ctx_t *
|
static lsquic_stream_ctx_t *
|
||||||
http_client_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
|
http_client_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
|
||||||
{
|
{
|
||||||
|
@ -205,6 +206,9 @@ http_client_on_new_stream (void *stream_if_ctx, lsquic_stream_t *stream)
|
||||||
static void
|
static void
|
||||||
send_headers (lsquic_stream_ctx_t *st_h)
|
send_headers (lsquic_stream_ctx_t *st_h)
|
||||||
{
|
{
|
||||||
|
const char *hostname = st_h->client_ctx->hostname;
|
||||||
|
if (!hostname)
|
||||||
|
hostname = st_h->client_ctx->prog->prog_hostname;
|
||||||
lsquic_http_header_t headers_arr[] = {
|
lsquic_http_header_t headers_arr[] = {
|
||||||
{
|
{
|
||||||
.name = { .iov_base = ":method", .iov_len = 7, },
|
.name = { .iov_base = ":method", .iov_len = 7, },
|
||||||
|
@ -222,8 +226,8 @@ send_headers (lsquic_stream_ctx_t *st_h)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = { ":authority", 10, },
|
.name = { ":authority", 10, },
|
||||||
.value = { .iov_base = (void *) st_h->client_ctx->hostname,
|
.value = { .iov_base = (void *) hostname,
|
||||||
.iov_len = strlen(st_h->client_ctx->hostname), },
|
.iov_len = strlen(hostname), },
|
||||||
},
|
},
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
@ -311,7 +315,7 @@ http_client_on_read (lsquic_stream_t *stream, lsquic_stream_ctx_t *st_h)
|
||||||
unsigned char buf[0x200];
|
unsigned char buf[0x200];
|
||||||
unsigned nreads = 0;
|
unsigned nreads = 0;
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
srand(GetTickCount());
|
srand(GetTickCount());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -407,7 +411,6 @@ usage (const char *prog)
|
||||||
"Usage: %s [opts]\n"
|
"Usage: %s [opts]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -6 MUST be entered before -s in order to work."
|
|
||||||
" -p PATH Path to request. May be specified more than once.\n"
|
" -p PATH Path to request. May be specified more than once.\n"
|
||||||
" -n CONNS Number of concurrent connections. Defaults to 1.\n"
|
" -n CONNS Number of concurrent connections. Defaults to 1.\n"
|
||||||
" -r NREQS Total number of requests to send. Defaults to 1.\n"
|
" -r NREQS Total number of requests to send. Defaults to 1.\n"
|
||||||
|
@ -420,8 +423,8 @@ usage (const char *prog)
|
||||||
" content-length\n"
|
" content-length\n"
|
||||||
" -K Discard server response\n"
|
" -K Discard server response\n"
|
||||||
" -I Abort on incomplete reponse from server\n"
|
" -I Abort on incomplete reponse from server\n"
|
||||||
" -6 IPv6 The client will try to connect via IPv6\n"
|
" -4 Prefer IPv4 when resolving hostname\n"
|
||||||
" if this flag is used. If not it will use IPv4.\n"
|
" -6 Prefer IPv6 when resolving hostname\n"
|
||||||
, prog);
|
, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,14 +439,11 @@ main (int argc, char **argv)
|
||||||
struct sport_head sports;
|
struct sport_head sports;
|
||||||
struct prog prog;
|
struct prog prog;
|
||||||
|
|
||||||
ipv6 = 0;
|
|
||||||
|
|
||||||
TAILQ_INIT(&sports);
|
TAILQ_INIT(&sports);
|
||||||
memset(&client_ctx, 0, sizeof(client_ctx));
|
memset(&client_ctx, 0, sizeof(client_ctx));
|
||||||
client_ctx.hcc_concurrency = 1;
|
client_ctx.hcc_concurrency = 1;
|
||||||
TAILQ_INIT(&client_ctx.hcc_path_elems);
|
TAILQ_INIT(&client_ctx.hcc_path_elems);
|
||||||
TAILQ_INIT(&client_ctx.conn_ctxs);
|
TAILQ_INIT(&client_ctx.conn_ctxs);
|
||||||
client_ctx.hostname = "localhost";
|
|
||||||
client_ctx.method = "GET";
|
client_ctx.method = "GET";
|
||||||
client_ctx.hcc_concurrency = 1;
|
client_ctx.hcc_concurrency = 1;
|
||||||
client_ctx.hcc_reqs_per_conn = 1;
|
client_ctx.hcc_reqs_per_conn = 1;
|
||||||
|
@ -456,11 +456,14 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
prog_init(&prog, LSENG_HTTP, &sports, &http_client_if, &client_ctx);
|
prog_init(&prog, LSENG_HTTP, &sports, &http_client_if, &client_ctx);
|
||||||
|
|
||||||
while (-1 != (opt = getopt(argc, argv, PROG_OPTS "6r:R:IKu:EP:M:n:H:p:h")))
|
while (-1 != (opt = getopt(argc, argv, PROG_OPTS "46r:R:IKu:EP:M:n:H:p:h")))
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case '4':
|
||||||
|
prog.prog_ipver = 4;
|
||||||
|
break;
|
||||||
case '6':
|
case '6':
|
||||||
ipv6 = 1;
|
prog.prog_ipver = 4;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
client_ctx.hcc_flags |= HCC_ABORT_ON_INCOMPLETE;
|
client_ctx.hcc_flags |= HCC_ABORT_ON_INCOMPLETE;
|
||||||
|
@ -505,7 +508,7 @@ main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
client_ctx.hostname = optarg;
|
client_ctx.hostname = optarg;
|
||||||
prog.prog_hostname = optarg; /* Pokes into prog */
|
prog.prog_hostname = optarg; /* Pokes into prog */
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
pe = calloc(1, sizeof(*pe));
|
pe = calloc(1, sizeof(*pe));
|
||||||
|
|
25
test/prog.c
25
test/prog.c
|
@ -83,12 +83,15 @@ void
|
||||||
prog_print_common_options (const struct prog *prog, FILE *out)
|
prog_print_common_options (const struct prog *prog, FILE *out)
|
||||||
{
|
{
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
" -s SVCPORT The port on which the client should connect.\n"
|
" -s SERVER Server address. Takes on the form of host:port, host,\n"
|
||||||
" If no -s option is given, port 443\n"
|
" or port. If host is not an IPv4 or IPv6 address, it is\n"
|
||||||
" is used.\n"
|
" resolved. If host is not set, the value of SNI is\n"
|
||||||
" You can also specify an certain ipadress to be used here.\n"
|
" use (see the -H flag). If port is not set, the default\n"
|
||||||
" To do that enter an ipadress and the port seperated by :\n"
|
" is 443. Examples:\n"
|
||||||
" e.g -s ::1:12345 or -s 0.0.0.0:12345 or -s 443 or -s example.com:443\n"
|
" 127.0.0.1:12345\n"
|
||||||
|
" ::1:12345\n"
|
||||||
|
" example.com\n"
|
||||||
|
" example.com:8443\n"
|
||||||
#if LSQUIC_DONTFRAG_SUPPORTED
|
#if LSQUIC_DONTFRAG_SUPPORTED
|
||||||
" -D Set `do not fragment' flag on outgoing UDP packets\n"
|
" -D Set `do not fragment' flag on outgoing UDP packets\n"
|
||||||
#endif
|
#endif
|
||||||
|
@ -124,8 +127,9 @@ prog_print_common_options (const struct prog *prog, FILE *out)
|
||||||
{
|
{
|
||||||
if (prog->prog_engine_flags & LSENG_HTTP)
|
if (prog->prog_engine_flags & LSENG_HTTP)
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
" -H host Value of `host' HTTP header. Defaults to `localhost'. This\n"
|
" -H host Value of `host' HTTP header. This is also used as SNI\n"
|
||||||
" is also used as SNI.\n"
|
" in Client Hello. This option is used to override the\n"
|
||||||
|
" `host' part of the address specified using -s flag.\n"
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
fprintf(out,
|
fprintf(out,
|
||||||
|
@ -176,7 +180,6 @@ prog_set_opt (struct prog *prog, int opt, const char *arg)
|
||||||
case 'o':
|
case 'o':
|
||||||
return set_engine_option(&prog->prog_settings,
|
return set_engine_option(&prog->prog_settings,
|
||||||
&prog->prog_version_cleared, arg);
|
&prog->prog_version_cleared, arg);
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
if (0 == (prog->prog_engine_flags & LSENG_SERVER) &&
|
if (0 == (prog->prog_engine_flags & LSENG_SERVER) &&
|
||||||
!TAILQ_EMPTY(prog->prog_sports))
|
!TAILQ_EMPTY(prog->prog_sports))
|
||||||
|
@ -373,7 +376,9 @@ prog_prep (struct prog *prog)
|
||||||
|
|
||||||
if (TAILQ_EMPTY(prog->prog_sports))
|
if (TAILQ_EMPTY(prog->prog_sports))
|
||||||
{
|
{
|
||||||
s = prog_add_sport(prog, "443");
|
if (!prog->prog_hostname)
|
||||||
|
return -1;
|
||||||
|
s = prog_add_sport(prog, prog->prog_hostname);
|
||||||
if (0 != s)
|
if (0 != s)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
#ifndef PROG_H
|
#ifndef PROG_H
|
||||||
#define PROG_H 1
|
#define PROG_H 1
|
||||||
|
|
||||||
int ipv6; /*True = Program uses ipv6, False = Program uses ipv4*/
|
|
||||||
|
|
||||||
struct event;
|
struct event;
|
||||||
struct event_base;
|
struct event_base;
|
||||||
struct lsquic_hash;
|
struct lsquic_hash;
|
||||||
|
@ -29,6 +27,7 @@ struct prog
|
||||||
struct sport_head *prog_sports;
|
struct sport_head *prog_sports;
|
||||||
struct lsquic_engine *prog_engine;
|
struct lsquic_engine *prog_engine;
|
||||||
const char *prog_hostname;
|
const char *prog_hostname;
|
||||||
|
int prog_ipver; /* 0, 4, or 6 */
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
|
|
||||||
|
@ -146,45 +148,6 @@ static void getExtensionPtrs()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int get_Ip_from_DNS(const char* hostname, struct service_port * sport, const char* port, int version)
|
|
||||||
{
|
|
||||||
struct sockaddr_in *const sa4 = (void *)&sport->sas;
|
|
||||||
struct sockaddr_in6 *const sa6 = (void *)&sport->sas;
|
|
||||||
struct addrinfo hints, *servinfo;
|
|
||||||
int rv;
|
|
||||||
char ip[INET6_ADDRSTRLEN];
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof(hints));
|
|
||||||
if (version)
|
|
||||||
hints.ai_family = AF_INET6;
|
|
||||||
else
|
|
||||||
hints.ai_family = AF_INET;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
|
|
||||||
if ((rv = getaddrinfo(hostname, port, &hints, &servinfo)) != 0){
|
|
||||||
LSQ_ERROR("getaddrinfo: %s\n", gai_strerror(rv));
|
|
||||||
freeaddrinfo(servinfo);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version){ /*Ipv6*/
|
|
||||||
memset(sa6, 0, sizeof(*sa6));
|
|
||||||
sa6->sin6_addr = ((struct sockaddr_in6*) servinfo->ai_addr)->sin6_addr;
|
|
||||||
sa6->sin6_family = AF_INET6;
|
|
||||||
sa6->sin6_port = htons(atoi(port));
|
|
||||||
inet_ntop(AF_INET6, &sa6->sin6_addr, ip, INET6_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
else{/*Ipv4*/
|
|
||||||
sa4->sin_addr = ((struct sockaddr_in *) servinfo->ai_addr)->sin_addr;
|
|
||||||
sa4->sin_family = AF_INET;
|
|
||||||
sa4->sin_port = htons(atoi(port));
|
|
||||||
inet_ntop(AF_INET, &sa4->sin_addr, ip, INET6_ADDRSTRLEN);
|
|
||||||
}
|
|
||||||
memcpy(sport->host, ip, sizeof(ip));
|
|
||||||
|
|
||||||
freeaddrinfo(servinfo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct packets_in *
|
static struct packets_in *
|
||||||
allocate_packets_in (SOCKET_TYPE fd)
|
allocate_packets_in (SOCKET_TYPE fd)
|
||||||
|
@ -250,6 +213,13 @@ struct service_port *
|
||||||
sport_new (const char *optarg, struct prog *prog)
|
sport_new (const char *optarg, struct prog *prog)
|
||||||
{
|
{
|
||||||
struct service_port *const sport = malloc(sizeof(*sport));
|
struct service_port *const sport = malloc(sizeof(*sport));
|
||||||
|
regex_t re;
|
||||||
|
regmatch_t matches[5];
|
||||||
|
int re_code, port, e;
|
||||||
|
const char *host;
|
||||||
|
const char *port_str;
|
||||||
|
struct addrinfo hints, *res = NULL;
|
||||||
|
char errbuf[80];
|
||||||
#if __linux__
|
#if __linux__
|
||||||
sport->n_dropped = 0;
|
sport->n_dropped = 0;
|
||||||
sport->drop_init = 0;
|
sport->drop_init = 0;
|
||||||
|
@ -264,51 +234,109 @@ sport_new (const char *optarg, struct prog *prog)
|
||||||
if (if_name)
|
if (if_name)
|
||||||
{
|
{
|
||||||
strncpy(sport->if_name, if_name + 1, sizeof(sport->if_name) - 1);
|
strncpy(sport->if_name, if_name + 1, sizeof(sport->if_name) - 1);
|
||||||
sport->if_name[sizeof(sport->if_name) - 1] = '\0';
|
sport->if_name[ sizeof(sport->if_name) - 1 ] = '\0';
|
||||||
*if_name = '\0';
|
*if_name = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sport->if_name[0] = '\0';
|
sport->if_name[0] = '\0';
|
||||||
#endif
|
#endif
|
||||||
|
re_code = regcomp(&re, "^(.*):([0-9][0-9]*)$"
|
||||||
char *port = strrchr(addr, ':');
|
"|^([0-9][0-9]*)$"
|
||||||
if (!port){/*IpAdress wasn't specified by the user*/
|
"|^(..*)$"
|
||||||
if (get_Ip_from_DNS(prog->prog_hostname, sport, addr, ipv6) == 1)
|
, REG_EXTENDED);
|
||||||
goto err;
|
if (re_code != 0)
|
||||||
|
{
|
||||||
|
regerror(re_code, &re, errbuf, sizeof(errbuf));
|
||||||
|
LSQ_ERROR("cannot compile regex: %s", errbuf);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
else {
|
if (0 != regexec(&re, addr, sizeof(matches) / sizeof(matches[0]),
|
||||||
*port = '\0';
|
matches, 0))
|
||||||
++port;
|
{
|
||||||
|
LSQ_ERROR("Invalid argument `%s'", addr);
|
||||||
struct sockaddr_in *const sa4 = (void *)&sport->sas;
|
goto err;
|
||||||
struct sockaddr_in6 *const sa6 = (void *)&sport->sas;
|
|
||||||
|
|
||||||
if (inet_pton(AF_INET, addr, &sa4->sin_addr)){
|
|
||||||
sa4->sin_family = AF_INET;
|
|
||||||
sa4->sin_port = htons(atoi(port));
|
|
||||||
|
|
||||||
if ((uintptr_t)port - (uintptr_t)addr > sizeof(sport->host))
|
|
||||||
goto err;
|
|
||||||
memcpy(sport->host, addr, port - addr);
|
|
||||||
}
|
|
||||||
else if (memset(sa6, 0, sizeof(*sa6)), inet_pton(AF_INET6, addr, &sa6->sin6_addr)){
|
|
||||||
sa6->sin6_family = AF_INET6;
|
|
||||||
sa6->sin6_port = htons(atoi(port));
|
|
||||||
|
|
||||||
if ((uintptr_t)port - (uintptr_t)addr > sizeof(sport->host))
|
|
||||||
goto err;
|
|
||||||
memcpy(sport->host, addr, port - addr);
|
|
||||||
}
|
|
||||||
else if (get_Ip_from_DNS(addr, sport, port, ipv6) != 0)
|
|
||||||
goto err;
|
|
||||||
}
|
}
|
||||||
|
if (matches[1].rm_so >= 0)
|
||||||
|
{
|
||||||
|
addr[ matches[1].rm_so + matches[1].rm_eo ] = '\0';
|
||||||
|
host = addr;
|
||||||
|
port_str = &addr[ matches[2].rm_so ];
|
||||||
|
port = atoi(port_str);
|
||||||
|
}
|
||||||
|
else if (matches[3].rm_so >= 0)
|
||||||
|
{
|
||||||
|
if (!prog->prog_hostname)
|
||||||
|
{
|
||||||
|
LSQ_ERROR("hostname is not specified");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
host = prog->prog_hostname;
|
||||||
|
port_str = &addr[ matches[3].rm_so ];
|
||||||
|
port = atoi(port_str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(matches[4].rm_so >= 0);
|
||||||
|
host = addr;
|
||||||
|
port_str = "443";
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
assert(host);
|
||||||
|
LSQ_DEBUG("host: %s; port: %d", host, port);
|
||||||
|
if (strlen(host) > sizeof(sport->host) - 1)
|
||||||
|
{
|
||||||
|
LSQ_ERROR("argument `%s' too long", host);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
strcpy(sport->host, host);
|
||||||
|
|
||||||
|
struct sockaddr_in *const sa4 = (void *) &sport->sas;
|
||||||
|
struct sockaddr_in6 *const sa6 = (void *) &sport->sas;
|
||||||
|
if (inet_pton(AF_INET, host, &sa4->sin_addr)) {
|
||||||
|
sa4->sin_family = AF_INET;
|
||||||
|
sa4->sin_port = htons(port);
|
||||||
|
} else if (memset(sa6, 0, sizeof(*sa6)),
|
||||||
|
inet_pton(AF_INET6, host, &sa6->sin6_addr)) {
|
||||||
|
sa6->sin6_family = AF_INET6;
|
||||||
|
sa6->sin6_port = htons(port);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
hints.ai_flags = AI_NUMERICSERV;
|
||||||
|
if (prog->prog_ipver == 4)
|
||||||
|
hints.ai_family = AF_INET;
|
||||||
|
else if (prog->prog_ipver == 6)
|
||||||
|
hints.ai_family = AF_INET6;
|
||||||
|
e = getaddrinfo(host, port_str, &hints, &res);
|
||||||
|
if (e != 0)
|
||||||
|
{
|
||||||
|
LSQ_ERROR("could not resolve %s:%s: %s", host, port_str,
|
||||||
|
gai_strerror(e));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
if (res->ai_addrlen > sizeof(sport->sas))
|
||||||
|
{
|
||||||
|
LSQ_ERROR("resolved socket length is too long");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memcpy(&sport->sas, res->ai_addr, res->ai_addrlen);
|
||||||
|
if (!prog->prog_hostname)
|
||||||
|
prog->prog_hostname = sport->host;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == re_code)
|
||||||
|
regfree(&re);
|
||||||
|
if (res)
|
||||||
|
freeaddrinfo(res);
|
||||||
free(addr);
|
free(addr);
|
||||||
sport->sp_prog = prog;
|
sport->sp_prog = prog;
|
||||||
return sport;
|
return sport;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
LSQ_ERROR("Couldn't resolve hostname or ip-address");
|
if (0 == re_code)
|
||||||
|
regfree(&re);
|
||||||
|
if (res)
|
||||||
|
freeaddrinfo(res);
|
||||||
free(sport);
|
free(sport);
|
||||||
free(addr);
|
free(addr);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -456,7 +484,7 @@ read_one_packet (struct read_iter *iter)
|
||||||
if (SOCKET_ERROR == socket_ret) {
|
if (SOCKET_ERROR == socket_ret) {
|
||||||
if (WSAEWOULDBLOCK != WSAGetLastError())
|
if (WSAEWOULDBLOCK != WSAGetLastError())
|
||||||
LSQ_ERROR("recvmsg: %d", WSAGetLastError());
|
LSQ_ERROR("recvmsg: %d", WSAGetLastError());
|
||||||
return ROP_ERROR;
|
return ROP_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -106,13 +106,4 @@ create_lsquic_reader_ctx (const char *filename);
|
||||||
void
|
void
|
||||||
destroy_lsquic_reader_ctx (struct reader_ctx *ctx);
|
destroy_lsquic_reader_ctx (struct reader_ctx *ctx);
|
||||||
|
|
||||||
/*Function resolves a Hostname into an Ip Adress
|
|
||||||
Parameters:
|
|
||||||
-hostname the URL of the website
|
|
||||||
-sport the service port structure that stores the ip
|
|
||||||
-port the port of the connection
|
|
||||||
-version 0 for ipv4 and 1 for ipv6
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
get_Ip_from_DNS(const char* hostname, struct service_port * sport, const char* port, int version);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue