1
0
mirror of https://github.com/irssi/irssi.git synced 2024-09-15 04:28:09 -04:00

/CONNECT, /SERVER: added -4 and -6 options for specifying if we should

connect to IPv4 or IPv6 address of the server. If -host or /SET
hostname is set irssi determines from it if it should use IPv4 or v6.


git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1192 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
Timo Sirainen 2001-02-09 21:26:50 +00:00 committed by cras
parent 6358c2d627
commit 8938a0f42b
8 changed files with 39 additions and 22 deletions

View File

@ -73,7 +73,7 @@ static int g_io_channel_read_block(GIOChannel *channel, void *data, int len)
/* nonblocking gethostbyname(), ip (IPADDR) + error (int, 0 = not error) is
written to pipe when found PID of the resolver child is returned */
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int family)
{
RESOLVED_IP_REC rec;
const char *errorstr;
@ -100,7 +100,7 @@ int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe)
/* child */
memset(&rec, 0, sizeof(rec));
rec.error = net_gethostbyname(addr, &rec.ip);
rec.error = net_gethostbyname(addr, &rec.ip, family);
if (rec.error == 0) {
errorstr = NULL;
} else {
@ -239,7 +239,8 @@ int net_connect_nonblock(const char *server, int port, const IPADDR *my_ip,
rec->pipes[1] = g_io_channel_unix_new(fd[1]);
/* start nonblocking host name lookup */
net_gethostbyname_nonblock(server, rec->pipes[1]);
net_gethostbyname_nonblock(server, rec->pipes[1],
my_ip == NULL ? 0 : my_ip->family);
rec->tag = g_input_add(rec->pipes[0], G_INPUT_READ,
(GInputFunction) simple_readpipe, rec);

View File

@ -24,7 +24,7 @@ typedef void (*NET_CALLBACK) (GIOChannel *, void *);
typedef void (*NET_HOST_CALLBACK) (RESOLVED_NAME_REC *, void *);
/* nonblocking gethostbyname(), PID of the resolver child is returned. */
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe);
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int family);
/* Get host's name, call func when finished */
int net_gethostbyaddr_nonblock(IPADDR *ip, NET_HOST_CALLBACK func, void *data);
/* get the resolved IP address. returns -1 if some error occured with read() */

View File

@ -137,10 +137,12 @@ int sin_get_port(union sockaddr_union *so)
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip)
{
IPADDR ip;
int family;
g_return_val_if_fail(addr != NULL, NULL);
if (net_gethostbyname(addr, &ip) == -1)
family = my_ip == NULL ? 0 : my_ip->family;
if (net_gethostbyname(addr, &ip, family) == -1)
return NULL;
return net_connect_ip(&ip, port, my_ip);
@ -332,11 +334,11 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
/* Get IP address for host, returns 0 = ok,
others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip)
int net_gethostbyname(const char *addr, IPADDR *ip, int family)
{
#ifdef HAVE_IPV6
union sockaddr_union *so;
struct addrinfo req, *ai;
struct addrinfo hints, *ai;
char hbuf[NI_MAXHOST];
int host_error;
#else
@ -347,11 +349,13 @@ int net_gethostbyname(const char *addr, IPADDR *ip)
#ifdef HAVE_IPV6
memset(ip, 0, sizeof(IPADDR));
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = family;
/* save error to host_error for later use */
host_error = getaddrinfo(addr, NULL, &req, &ai);
host_error = getaddrinfo(addr, NULL, &hints, &ai);
if (host_error != 0)
return host_error;

View File

@ -50,9 +50,10 @@ int net_receive(GIOChannel *handle, char *buf, int len);
/* Transmit data, return number of bytes sent, -1 = error */
int net_transmit(GIOChannel *handle, const char *data, int len);
/* Get IP address for host, returns 0 = ok,
others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip);
/* Get IP address for host. family specifies if we should prefer to
IPv4 or IPv6 address (0 = don't care, AF_INET or AF_INET6).
returns 0 = ok, others = error code for net_gethosterror() */
int net_gethostbyname(const char *addr, IPADDR *ip, int family);
/* Get name for host, *name should be g_free()'d unless it's NULL.
Return values are the same as with net_gethostbyname() */
int net_gethostbyaddr(IPADDR *ip, char **name);

View File

@ -8,6 +8,7 @@ char *proxy;
int proxy_port;
char *proxy_string;
unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */
char *address;
int port;
char *chatnet;

View File

@ -42,7 +42,7 @@ static void get_source_host_ip(void)
/* FIXME: This will block! */
source_host_ok = *settings_get_str("hostname") != '\0' &&
net_gethostbyname(settings_get_str("hostname"), &ip) == 0;
net_gethostbyname(settings_get_str("hostname"), &ip, 0) == 0;
if (source_host_ok) {
if (source_host_ip == NULL)
source_host_ip = g_new(IPADDR, 1);
@ -65,7 +65,7 @@ static void conn_set_ip(SERVER_CONNECT_REC *conn,
/* resolve the IP and use it */
if (net_gethostbyname(own_host, &ip) == 0) {
if (net_gethostbyname(own_host, &ip, conn->family) == 0) {
if (conn->own_ip == NULL)
conn->own_ip = g_new(IPADDR, 1);
memcpy(conn->own_ip, &ip, sizeof(IPADDR));

View File

@ -256,13 +256,17 @@ int server_start_connect(SERVER_REC *server)
}
server->connect_pipe[0] = g_io_channel_unix_new(fd[0]);
server->connect_pipe[1] = g_io_channel_unix_new(fd[1]);
server->connect_pipe[1] = g_io_channel_unix_new(fd[1]);
if (server->connrec->family == 0 && server->connrec->own_ip != NULL)
server->connrec->family = server->connrec->own_ip->family;
connect_address = server->connrec->proxy != NULL ?
server->connrec->proxy : server->connrec->address;
server->connect_pid =
net_gethostbyname_nonblock(connect_address,
server->connect_pipe[1]);
server->connect_pipe[1],
server->connrec->family);
server->connect_tag =
g_input_add(server->connect_pipe[0], G_INPUT_READ,
(GInputFunction) server_connect_callback_readpipe,

View File

@ -64,7 +64,8 @@ static SERVER_REC *irc_connect_server(const char *data)
g_return_val_if_fail(data != NULL, NULL);
if (!cmd_get_params(data, &free_arg, 4 | PARAM_FLAG_OPTIONS,
"connect", &optlist, &addr, &portstr, &password, &nick))
"connect", &optlist, &addr, &portstr,
&password, &nick))
return NULL;
if (*addr == '+') addr++;
if (*addr == '\0') {
@ -78,6 +79,11 @@ static SERVER_REC *irc_connect_server(const char *data)
/* connect to server */
conn = server_create_conn(addr, atoi(portstr), password, nick);
if (g_hash_table_lookup(optlist, "6") != NULL)
conn->family = AF_INET6;
else if (g_hash_table_lookup(optlist, "4") != NULL)
conn->family = AF_INET;
ircnet = g_hash_table_lookup(optlist, "ircnet");
if (ircnet != NULL && *ircnet != '\0') {
g_free_not_null(conn->chatnet);
@ -87,7 +93,7 @@ static SERVER_REC *irc_connect_server(const char *data)
if (host != NULL && *host != '\0') {
IPADDR ip;
if (net_gethostbyname(host, &ip) == 0) {
if (net_gethostbyname(host, &ip, conn->family) == 0) {
if (conn->own_ip == NULL)
conn->own_ip = g_new(IPADDR, 1);
memcpy(conn->own_ip, &ip, sizeof(IPADDR));
@ -99,7 +105,7 @@ static SERVER_REC *irc_connect_server(const char *data)
return server;
}
/* SYNTAX: CONNECT [-ircnet <ircnet>] [-host <hostname>]
/* SYNTAX: CONNECT [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
<address>|<ircnet> [<port> [<password> [<nick>]]] */
static void cmd_connect(const char *data)
{
@ -137,7 +143,7 @@ static RECONNECT_REC *find_reconnect_server(const char *addr, int port)
return match;
}
/* SYNTAX: SERVER [-ircnet <ircnet>] [-host <hostname>]
/* SYNTAX: SERVER [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
[+]<address>|<ircnet> [<port> [<password> [<nick>]]] */
static void cmd_server(const char *data, IRC_SERVER_REC *server,
void *item)
@ -1212,7 +1218,7 @@ void irc_commands_init(void)
signal_add("whois event", (SIGNAL_FUNC) event_whois);
signal_add("whowas event", (SIGNAL_FUNC) event_whowas);
command_set_options("connect", "+ircnet +host");
command_set_options("connect", "4 6 +ircnet +host");
command_set_options("topic", "delete");
command_set_options("list", "yes");
command_set_options("away", "one all");