mirror of
https://github.com/irssi/irssi.git
synced 2025-02-02 15:08:01 -05: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:
parent
6358c2d627
commit
8938a0f42b
@ -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);
|
||||
|
||||
|
@ -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() */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user