mirror of
https://github.com/irssi/irssi.git
synced 2026-08-08 19:30:15 +02:00
Merge pull request #1580 from ailin-nemui/gio-resolver
use GIO resolver
This commit is contained in:
commit
62031f5bdc
19 changed files with 318 additions and 344 deletions
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
%9Examples:%9
|
||||
|
||||
/TOGGLE resolve_prefer_ipv6
|
||||
/TOGGLE channels_rejoin_unavailable ON
|
||||
|
||||
%9See also:%9 SET
|
||||
|
|
|
|||
|
|
@ -373,9 +373,6 @@
|
|||
After connected to server, Irssi can automatically change your user
|
||||
mode. You can set it with /SET usermode <mode>, default is +i.
|
||||
|
||||
/SET resolve_prefer_ipv6 - If ON, prefer IPv6 for hosts that
|
||||
have both v4 and v6 addresses.
|
||||
|
||||
5.5 Automatic reconnecting
|
||||
|
||||
If you get disconnected from server, Irssi will try to reconnect
|
||||
|
|
|
|||
37
meson.build
37
meson.build
|
|
@ -6,8 +6,9 @@ project('irssi', 'c',
|
|||
############################
|
||||
############################
|
||||
|
||||
glib_internal_version = 'glib-2.74.3' # keep this in sync with subprojects/glib.wrap
|
||||
glib_internal_version = 'glib-2.74.7' # keep this in sync with subprojects/glib.wrap
|
||||
glib_pcre2_internal_version = 'pcre2-10.40'
|
||||
glib_libffi_internal_version = 'libffi'
|
||||
cc = meson.get_compiler('c')
|
||||
rootinc = include_directories('.')
|
||||
dep = []
|
||||
|
|
@ -217,11 +218,6 @@ if not glib_dep.found()
|
|||
prov_lib = cc.find_library('iconv', dirs : '/usr/local/lib')
|
||||
glib_internal_usr_local = true
|
||||
endif
|
||||
if cc.has_function('libiconv_open', dependencies : prov_lib)
|
||||
glib_internal_configure_args += '-Diconv=gnu'
|
||||
else
|
||||
glib_internal_configure_args += '-Diconv=native'
|
||||
endif
|
||||
glib_internal_dependencies += prov_lib
|
||||
endif
|
||||
|
||||
|
|
@ -254,7 +250,7 @@ if not glib_dep.found()
|
|||
glib_internal_configure_t = custom_target('glib-internal-configure',
|
||||
command : [ meson_cmd, 'setup', '--prefix=/irssi-glib-internal',
|
||||
'--buildtype=' + get_option('buildtype'),
|
||||
'-Dlibmount=disabled', '-Dselinux=disabled', '-Ddefault_library=static', '-Dforce_fallback_for=pcre2',
|
||||
'-Dlibmount=disabled', '-Dselinux=disabled', '-Ddefault_library=static', '-Dforce_fallback_for=pcre2,libffi',
|
||||
glib_internal_configure_args,
|
||||
(meson.current_build_dir() / 'build-subprojects' / 'glib'),
|
||||
(meson.current_source_dir() / 'subprojects' / glib_internal_version) ],
|
||||
|
|
@ -263,9 +259,13 @@ if not glib_dep.found()
|
|||
depends : glib_internal_download_t,)
|
||||
glib_internal_build_t = custom_target('glib-internal-build',
|
||||
command : [ ninja, '-C', meson.current_build_dir() / 'build-subprojects' / 'glib',
|
||||
'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a',
|
||||
'subprojects' / glib_pcre2_internal_version / 'libpcre2-8.a',
|
||||
'glib' / 'libglib-2.0.a',
|
||||
'gmodule' / 'libgmodule-2.0.a'],
|
||||
'gmodule' / 'libgmodule-2.0.a',
|
||||
'gobject' / 'libgobject-2.0.a',
|
||||
'gio' / 'libgio-2.0.a',
|
||||
],
|
||||
console : true,
|
||||
output : ['glib-internal-build'],
|
||||
depends : glib_internal_configure_t,)
|
||||
|
|
@ -295,11 +295,32 @@ if not glib_dep.found()
|
|||
],
|
||||
link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gmodule' / 'libgmodule-2.0.a' ],
|
||||
)
|
||||
gobject_dep = declare_dependency(sources : glib_internal_build_t,
|
||||
compile_args : [
|
||||
'-isystem' + (meson.current_build_dir() / 'build-subprojects' / 'glib'),
|
||||
],
|
||||
link_args : [
|
||||
meson.current_build_dir() / 'build-subprojects' / 'glib' / 'subprojects' / glib_libffi_internal_version / 'src' / 'libffi.a',
|
||||
meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gobject' / 'libgobject-2.0.a'
|
||||
],
|
||||
)
|
||||
gio_dep = declare_dependency(sources : glib_internal_build_t,
|
||||
dependencies : cc.find_library('z'),
|
||||
compile_args : [
|
||||
'-isystem' + (meson.current_source_dir() / 'subprojects' / glib_internal_version / 'gio'),
|
||||
'-isystem' + (meson.current_build_dir() / 'build-subprojects' / 'glib'),
|
||||
],
|
||||
link_args : [ meson.current_build_dir() / 'build-subprojects' / 'glib' / 'gio' / 'libgio-2.0.a' ],
|
||||
)
|
||||
else
|
||||
gmodule_dep = dependency('gmodule-2.0', static : want_static_dependency, include_type : 'system')
|
||||
gobject_dep = dependency('gobject-2.0', static : want_static_dependency, include_type : 'system')
|
||||
gio_dep = dependency('gio-2.0', static : want_static_dependency, include_type : 'system')
|
||||
endif
|
||||
dep += glib_dep
|
||||
dep += gmodule_dep
|
||||
dep += gobject_dep
|
||||
dep += gio_dep
|
||||
|
||||
if glib_internal and want_static_dependency and want_fuzzer
|
||||
openssl_proj = subproject('openssl', default_options : ['default_library=static', 'asm=disabled'])
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#define IRSSI_GLOBAL_CONFIG "irssi.conf" /* config file name in /etc/ */
|
||||
#define IRSSI_HOME_CONFIG "config" /* config file name in ~/.irssi/ */
|
||||
|
||||
#define IRSSI_ABI_VERSION 56
|
||||
#define IRSSI_ABI_VERSION 57
|
||||
|
||||
#define DEFAULT_SERVER_ADD_PORT 6667
|
||||
#define DEFAULT_SERVER_ADD_TLS_PORT 6697
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <gmodule.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
typedef guint64 uoff_t;
|
||||
#define PRIuUOFF_T G_GUINT64_FORMAT
|
||||
|
|
|
|||
|
|
@ -101,10 +101,11 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
|
|||
|
||||
host = g_hash_table_lookup(optlist, "host");
|
||||
if (host != NULL && *host != '\0') {
|
||||
IPADDR ip4, ip6;
|
||||
|
||||
if (net_gethostbyname(host, &ip4, &ip6) == 0)
|
||||
server_connect_own_ip_save(conn, &ip4, &ip6);
|
||||
IPADDR ip4 = { 0 };
|
||||
IPADDR ip6 = { 0 };
|
||||
if (net_gethostbyname_first_ips(host, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, &ip4,
|
||||
&ip6) == 0)
|
||||
server_connect_own_ip_save(conn, &ip4, &ip6);
|
||||
}
|
||||
|
||||
cmd_params_free(free_arg);
|
||||
|
|
|
|||
|
|
@ -22,86 +22,54 @@
|
|||
|
||||
#include <signal.h>
|
||||
|
||||
#include <irssi/src/core/pidwait.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
#include <irssi/src/core/net-nonblock.h>
|
||||
|
||||
/* 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 reverse_lookup)
|
||||
{
|
||||
RESOLVED_IP_REC rec;
|
||||
const char *errorstr;
|
||||
int pid;
|
||||
typedef struct {
|
||||
NetGethostbynameContinuationFunc cont;
|
||||
void *cont_data;
|
||||
} NET_GETHOSTBYNAME_CALLBACK_DATA;
|
||||
|
||||
(void) reverse_lookup; /* Kept for API backward compatibility */
|
||||
static void net_gethostbyname_callback(GResolver *resolver, GAsyncResult *result,
|
||||
NET_GETHOSTBYNAME_CALLBACK_DATA *data)
|
||||
{
|
||||
/* GList<GInetAddress> */
|
||||
GList *ailist;
|
||||
GError *error;
|
||||
RESOLVED_IP_REC *iprec;
|
||||
|
||||
error = NULL;
|
||||
ailist = g_resolver_lookup_by_name_with_flags_finish(resolver, result, &error);
|
||||
iprec = g_new0(RESOLVED_IP_REC, 1);
|
||||
if (error != NULL) {
|
||||
iprec->error = error;
|
||||
} else {
|
||||
iprec->ailist = ailist;
|
||||
}
|
||||
g_object_unref(resolver);
|
||||
resolved_ip_ref(iprec);
|
||||
|
||||
data->cont(iprec, data->cont_data);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
/* nonblocking gethostbyname() */
|
||||
GCancellable *net_gethostbyname_nonblock(const char *addr, GResolverNameLookupFlags flags,
|
||||
NetGethostbynameContinuationFunc cont, void *cont_data)
|
||||
{
|
||||
GResolver *resolver;
|
||||
GCancellable *cancellable;
|
||||
NET_GETHOSTBYNAME_CALLBACK_DATA *data;
|
||||
|
||||
g_return_val_if_fail(addr != NULL, FALSE);
|
||||
|
||||
pid = fork();
|
||||
if (pid > 0) {
|
||||
/* parent */
|
||||
pidwait_add(pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
if (pid != 0) {
|
||||
/* failed! */
|
||||
g_warning("net_connect_thread(): fork() failed! "
|
||||
"Using blocking resolving");
|
||||
}
|
||||
|
||||
/* child */
|
||||
srand(time(NULL));
|
||||
|
||||
memset(&rec, 0, sizeof(rec));
|
||||
rec.error = net_gethostbyname(addr, &rec.ip4, &rec.ip6);
|
||||
if (rec.error == 0) {
|
||||
errorstr = NULL;
|
||||
} else {
|
||||
errorstr = net_gethosterror(rec.error);
|
||||
rec.errlen = errorstr == NULL ? 0 : strlen(errorstr)+1;
|
||||
}
|
||||
|
||||
i_io_channel_write_block(pipe, &rec, sizeof(rec));
|
||||
if (rec.errlen != 0)
|
||||
i_io_channel_write_block(pipe, (void *) errorstr, rec.errlen);
|
||||
|
||||
if (pid == 0)
|
||||
_exit(99);
|
||||
|
||||
/* we used blocking lookup */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get the resolved IP address */
|
||||
int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec)
|
||||
{
|
||||
rec->error = -1;
|
||||
rec->errorstr = NULL;
|
||||
|
||||
fcntl(g_io_channel_unix_get_fd(pipe), F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* get ip+error */
|
||||
if (i_io_channel_read_block(pipe, rec, sizeof(*rec)) == -1) {
|
||||
rec->errorstr = g_strdup_printf("Host name lookup: %s",
|
||||
g_strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rec->error) {
|
||||
/* read error string, if we can't read everything for some
|
||||
reason, just ignore it. */
|
||||
rec->errorstr = g_malloc0(rec->errlen+1);
|
||||
i_io_channel_read_block(pipe, rec->errorstr, rec->errlen);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Kill the resolver child */
|
||||
void net_disconnect_nonblock(int pid)
|
||||
{
|
||||
g_return_if_fail(pid > 0);
|
||||
|
||||
kill(pid, SIGKILL);
|
||||
resolver = g_resolver_get_default();
|
||||
cancellable = g_cancellable_new();
|
||||
data = g_new0(NET_GETHOSTBYNAME_CALLBACK_DATA, 1);
|
||||
data->cont = cont;
|
||||
data->cont_data = cont_data;
|
||||
g_resolver_lookup_by_name_with_flags_async(resolver, addr, flags, cancellable,
|
||||
(GAsyncReadyCallback) net_gethostbyname_callback,
|
||||
data);
|
||||
return cancellable;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,20 +3,10 @@
|
|||
|
||||
#include <irssi/src/core/network.h>
|
||||
|
||||
typedef struct {
|
||||
IPADDR ip4, ip6; /* resolved ip addresses */
|
||||
int error; /* error, 0 = no error, -1 = error: */
|
||||
int errlen; /* error text length */
|
||||
char *errorstr; /* error string - dynamically allocated, you'll
|
||||
need to free() it yourself unless it's NULL */
|
||||
} RESOLVED_IP_REC;
|
||||
typedef void (*NetGethostbynameContinuationFunc)(RESOLVED_IP_REC *, void *);
|
||||
|
||||
/* nonblocking gethostbyname(), PID of the resolver child is returned. */
|
||||
int net_gethostbyname_nonblock(const char *addr, GIOChannel *pipe, int reverse_lookup);
|
||||
/* get the resolved IP address. returns -1 if some error occurred with read() */
|
||||
int net_gethostbyname_return(GIOChannel *pipe, RESOLVED_IP_REC *rec);
|
||||
|
||||
/* Kill the resolver child */
|
||||
void net_disconnect_nonblock(int pid);
|
||||
/* nonblocking gethostbyname(), Cancellable of the resolver child is returned. */
|
||||
GCancellable *net_gethostbyname_nonblock(const char *addr, GResolverNameLookupFlags flags,
|
||||
NetGethostbynameContinuationFunc cont, void *cont_data);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -81,27 +81,6 @@ int i_io_channel_read_block(GIOChannel *channel, void *data, int len)
|
|||
return received < len ? -1 : 0;
|
||||
}
|
||||
|
||||
IPADDR ip4_any = {
|
||||
AF_INET,
|
||||
#if defined(IN6ADDR_ANY_INIT)
|
||||
IN6ADDR_ANY_INIT
|
||||
#else
|
||||
{ INADDR_ANY }
|
||||
#endif
|
||||
};
|
||||
|
||||
int net_ip_compare(IPADDR *ip1, IPADDR *ip2)
|
||||
{
|
||||
if (ip1->family != ip2->family)
|
||||
return 0;
|
||||
|
||||
if (ip1->family == AF_INET6)
|
||||
return memcmp(&ip1->ip, &ip2->ip, sizeof(ip1->ip)) == 0;
|
||||
|
||||
return memcmp(&ip1->ip, &ip2->ip, 4) == 0;
|
||||
}
|
||||
|
||||
|
||||
static void sin_set_ip(union sockaddr_union *so, const IPADDR *ip)
|
||||
{
|
||||
if (ip == NULL) {
|
||||
|
|
@ -392,95 +371,87 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Get IP addresses for host, both IPv4 and IPv6 if possible.
|
||||
If ip->family is 0, the address wasn't found.
|
||||
Returns 0 = ok, others = error code for net_gethosterror() */
|
||||
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
|
||||
void resolved_ip_ref(RESOLVED_IP_REC *iprec)
|
||||
{
|
||||
union sockaddr_union *so;
|
||||
struct addrinfo hints, *ai, *ailist;
|
||||
int ret, count_v4, count_v6, use_v4, use_v6;
|
||||
iprec->refcount++;
|
||||
}
|
||||
|
||||
int resolved_ip_unref(RESOLVED_IP_REC *iprec)
|
||||
{
|
||||
if (--iprec->refcount > 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_resolver_free_addresses(iprec->ailist);
|
||||
if (iprec->error != NULL) {
|
||||
g_error_free(iprec->error);
|
||||
}
|
||||
g_free(iprec);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get IP addresses for host, both IPv4 and IPv6 if possible. */
|
||||
static RESOLVED_IP_REC *net_gethostbyname(const char *addr, GResolverNameLookupFlags flags)
|
||||
{
|
||||
/* GList<GInetAddress> */
|
||||
GList *ailist;
|
||||
GError *error;
|
||||
GResolver *resolver;
|
||||
RESOLVED_IP_REC *iprec;
|
||||
|
||||
#ifdef HAVE_CAPSICUM
|
||||
if (capsicum_enabled())
|
||||
return (capsicum_net_gethostbyname(addr, ip4, ip6));
|
||||
return (capsicum_net_gethostbyname(addr, flags));
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail(addr != NULL, -1);
|
||||
g_return_val_if_fail(addr != NULL, NULL);
|
||||
|
||||
memset(ip4, 0, sizeof(IPADDR));
|
||||
memset(ip6, 0, sizeof(IPADDR));
|
||||
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_ADDRCONFIG;
|
||||
|
||||
/* save error to host_error for later use */
|
||||
ret = getaddrinfo(addr, NULL, &hints, &ailist);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
/* count IPs */
|
||||
count_v4 = count_v6 = 0;
|
||||
for (ai = ailist; ai != NULL; ai = ai->ai_next) {
|
||||
if (ai->ai_family == AF_INET)
|
||||
count_v4++;
|
||||
else if (ai->ai_family == AF_INET6)
|
||||
count_v6++;
|
||||
error = NULL;
|
||||
resolver = g_resolver_get_default();
|
||||
ailist = g_resolver_lookup_by_name_with_flags(resolver, addr, flags, NULL, &error);
|
||||
iprec = g_new0(RESOLVED_IP_REC, 1);
|
||||
if (error != NULL) {
|
||||
iprec->error = error;
|
||||
} else {
|
||||
iprec->ailist = ailist;
|
||||
}
|
||||
g_object_unref(resolver);
|
||||
resolved_ip_ref(iprec);
|
||||
|
||||
if (count_v4 == 0 && count_v6 == 0)
|
||||
return EAI_NONAME; /* shouldn't happen? */
|
||||
|
||||
/* if there are multiple addresses, return random one */
|
||||
use_v4 = count_v4 <= 1 ? 0 : rand() % count_v4;
|
||||
use_v6 = count_v6 <= 1 ? 0 : rand() % count_v6;
|
||||
|
||||
count_v4 = count_v6 = 0;
|
||||
for (ai = ailist; ai != NULL; ai = ai->ai_next) {
|
||||
so = (union sockaddr_union *) ai->ai_addr;
|
||||
|
||||
if (ai->ai_family == AF_INET) {
|
||||
if (use_v4 == count_v4)
|
||||
sin_get_ip(so, ip4);
|
||||
count_v4++;
|
||||
} else if (ai->ai_family == AF_INET6) {
|
||||
if (use_v6 == count_v6)
|
||||
sin_get_ip(so, ip6);
|
||||
count_v6++;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(ailist);
|
||||
return 0;
|
||||
return iprec;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
int net_gethostbyname_first_ips(const char *addr, GResolverNameLookupFlags flags, IPADDR *ip4,
|
||||
IPADDR *ip6)
|
||||
{
|
||||
union sockaddr_union so;
|
||||
int host_error;
|
||||
char hostname[NI_MAXHOST];
|
||||
RESOLVED_IP_REC *iprec;
|
||||
|
||||
g_return_val_if_fail(ip != NULL, -1);
|
||||
g_return_val_if_fail(name != NULL, -1);
|
||||
iprec = net_gethostbyname(addr, flags);
|
||||
if (iprec->error == NULL) {
|
||||
GList *curr;
|
||||
|
||||
*name = NULL;
|
||||
for (curr = iprec->ailist; curr->next; curr = curr->next) {
|
||||
unsigned short family;
|
||||
GInetAddress *addr;
|
||||
|
||||
memset(&so, 0, sizeof(so));
|
||||
sin_set_ip(&so, ip);
|
||||
addr = curr->data;
|
||||
family = g_inet_address_get_family(addr);
|
||||
if (ip4->family == 0 && family == AF_INET) {
|
||||
ip4->family = AF_INET;
|
||||
memcpy(&ip4->ip, g_inet_address_to_bytes(addr), sizeof(ip4->ip));
|
||||
} else if (ip6->family == 0 && family == AF_INET6) {
|
||||
ip6->family = AF_INET6;
|
||||
memcpy(&ip6->ip, g_inet_address_to_bytes(addr), sizeof(ip6->ip));
|
||||
}
|
||||
}
|
||||
|
||||
/* save error to host_error for later use */
|
||||
host_error = getnameinfo((struct sockaddr *)&so, sizeof(so),
|
||||
hostname, sizeof(hostname),
|
||||
NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (host_error != 0)
|
||||
return host_error;
|
||||
|
||||
*name = g_strdup(hostname);
|
||||
|
||||
return 0;
|
||||
resolved_ip_unref(iprec);
|
||||
return 0;
|
||||
} else {
|
||||
resolved_ip_unref(iprec);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int net_ip2host(IPADDR *ip, char *host)
|
||||
|
|
@ -519,29 +490,6 @@ int net_geterror(GIOChannel *handle)
|
|||
return data;
|
||||
}
|
||||
|
||||
/* get error of net_gethostname() */
|
||||
const char *net_gethosterror(int error)
|
||||
{
|
||||
g_return_val_if_fail(error != 0, NULL);
|
||||
|
||||
if (error == EAI_SYSTEM) {
|
||||
return strerror(errno);
|
||||
} else {
|
||||
return gai_strerror(error);
|
||||
}
|
||||
}
|
||||
|
||||
/* return TRUE if host lookup failed because it didn't exist (ie. not
|
||||
some error with name server) */
|
||||
int net_hosterror_notfound(int error)
|
||||
{
|
||||
#ifdef EAI_NODATA /* NODATA is deprecated */
|
||||
return error != 1 && (error == EAI_NONAME || error == EAI_NODATA);
|
||||
#else
|
||||
return error != 1 && (error == EAI_NONAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get name of TCP service */
|
||||
char *net_getservbyport(int port)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <irssi/src/common.h>
|
||||
|
||||
#ifndef AF_INET6
|
||||
# ifdef PF_INET6
|
||||
|
|
@ -20,6 +21,13 @@ struct _IPADDR {
|
|||
struct in6_addr ip;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int refcount;
|
||||
/* GList<GInetAddress> */
|
||||
GList *ailist; /* needs to be freed */
|
||||
GError *error; /* needs to be freed */
|
||||
} RESOLVED_IP_REC;
|
||||
|
||||
/* maxmimum string length of IP address */
|
||||
#define MAX_IP_LEN INET6_ADDRSTRLEN
|
||||
|
||||
|
|
@ -29,9 +37,7 @@ extern IPADDR ip4_any;
|
|||
|
||||
GIOChannel *i_io_channel_new(int handle);
|
||||
|
||||
/* Returns 1 if IPADDRs are the same. */
|
||||
/* Deprecated since it is unused. It will be deleted in a later release. */
|
||||
int net_ip_compare(IPADDR *ip1, IPADDR *ip2) G_GNUC_DEPRECATED;
|
||||
/* OTR */
|
||||
int i_io_channel_write_block(GIOChannel *channel, void *data, int len);
|
||||
int i_io_channel_read_block(GIOChannel *channel, void *data, int len);
|
||||
|
||||
|
|
@ -60,18 +66,9 @@ 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 addresses for host, both IPv4 and IPv6 if possible.
|
||||
If ip->family is 0, the address wasn't found.
|
||||
Returns 0 = ok, others = error code for net_gethosterror() */
|
||||
int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6);
|
||||
/* 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);
|
||||
/* get error of net_gethostname() */
|
||||
const char *net_gethosterror(int error);
|
||||
/* return TRUE if host lookup failed because it didn't exist (ie. not
|
||||
some error with name server) */
|
||||
int net_hosterror_notfound(int error);
|
||||
/* Get the first IP address for host, both IPv4 and IPv6 if possible. */
|
||||
int net_gethostbyname_first_ips(const char *addr, GResolverNameLookupFlags flags, IPADDR *ip4,
|
||||
IPADDR *ip6);
|
||||
|
||||
/* Get socket address/port */
|
||||
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port);
|
||||
|
|
@ -90,4 +87,7 @@ char *net_getservbyport(int port);
|
|||
int is_ipv4_address(const char *host);
|
||||
int is_ipv6_address(const char *host);
|
||||
|
||||
void resolved_ip_ref(RESOLVED_IP_REC *iprec);
|
||||
int resolved_ip_unref(RESOLVED_IP_REC *iprec);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ unsigned int unix_socket:1; /* Connect using named unix socket */
|
|||
unsigned int use_tls:1; /* this connection uses TLS */
|
||||
unsigned int tls_verify:1;
|
||||
unsigned int no_connect:1; /* don't connect() at all, it's done by plugin */
|
||||
unsigned short last_failed_family; /* #641: if we failed to connect to ipv6, try ipv4 and vice versa */
|
||||
int last_connected;
|
||||
int last_failed;
|
||||
RESOLVED_IP_REC *resolved_host;
|
||||
char *channels;
|
||||
char *away_reason;
|
||||
|
|
|
|||
|
|
@ -21,10 +21,8 @@ unsigned int no_reconnect:1; /* Don't reconnect to server */
|
|||
NET_SENDBUF_REC *handle;
|
||||
int readtag; /* input tag */
|
||||
|
||||
/* for net_gethostbyname_return() */
|
||||
GIOChannel *connect_pipe[2];
|
||||
GCancellable *connect_cancellable;
|
||||
int connect_tag;
|
||||
int connect_pid;
|
||||
|
||||
RAWLOG_REC *rawlog;
|
||||
GHashTable *module_data;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,10 @@ static int server_reconnect_timeout(void)
|
|||
if (server->connect_tag != -1) {
|
||||
g_source_remove(server->connect_tag);
|
||||
server->connect_tag = -1;
|
||||
} else if (server->connect_cancellable != NULL) {
|
||||
g_cancellable_cancel(server->connect_cancellable);
|
||||
g_object_unref(server->connect_cancellable);
|
||||
server->connect_cancellable = NULL;
|
||||
}
|
||||
server->connection_lost = TRUE;
|
||||
server_connect_failed(server, "Timeout");
|
||||
|
|
@ -168,7 +172,8 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
|
|||
server_connect_ref(dest);
|
||||
dest->type = module_get_uniq_id("SERVER CONNECT", 0);
|
||||
dest->reconnection = src->reconnection;
|
||||
dest->last_failed_family = src->last_failed_family;
|
||||
dest->last_connected = src->last_connected;
|
||||
dest->last_failed = src->last_failed;
|
||||
dest->proxy = g_strdup(src->proxy);
|
||||
dest->proxy_port = src->proxy_port;
|
||||
dest->proxy_string = g_strdup(src->proxy_string);
|
||||
|
|
@ -207,6 +212,10 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
|
|||
dest->own_ip6 = g_new(IPADDR, 1);
|
||||
memcpy(dest->own_ip6, src->own_ip6, sizeof(IPADDR));
|
||||
}
|
||||
dest->resolved_host = src->resolved_host;
|
||||
if (dest->resolved_host != NULL) {
|
||||
resolved_ip_ref(dest->resolved_host);
|
||||
}
|
||||
|
||||
dest->channels = g_strdup(src->channels);
|
||||
dest->away_reason = g_strdup(src->away_reason);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ static void save_ips(IPADDR *ip4, IPADDR *ip6,
|
|||
static void get_source_host_ip(void)
|
||||
{
|
||||
const char *hostname;
|
||||
IPADDR ip4, ip6;
|
||||
IPADDR ip4 = { 0 };
|
||||
IPADDR ip6 = { 0 };
|
||||
|
||||
if (source_host_ok)
|
||||
return;
|
||||
|
|
@ -66,7 +67,8 @@ static void get_source_host_ip(void)
|
|||
/* FIXME: This will block! */
|
||||
hostname = settings_get_str("hostname");
|
||||
source_host_ok = *hostname != '\0' &&
|
||||
net_gethostbyname(hostname, &ip4, &ip6) == 0;
|
||||
net_gethostbyname_first_ips(hostname, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
|
||||
&ip4, &ip6) == 0;
|
||||
|
||||
if (source_host_ok)
|
||||
save_ips(&ip4, &ip6, &source_host_ip4, &source_host_ip6);
|
||||
|
|
@ -79,12 +81,14 @@ static void get_source_host_ip(void)
|
|||
static void conn_set_ip(SERVER_CONNECT_REC *conn, const char *own_host,
|
||||
IPADDR **own_ip4, IPADDR **own_ip6)
|
||||
{
|
||||
IPADDR ip4, ip6;
|
||||
IPADDR ip4 = { 0 };
|
||||
IPADDR ip6 = { 0 };
|
||||
|
||||
if (*own_ip4 == NULL && *own_ip6 == NULL) {
|
||||
/* resolve the IP */
|
||||
if (net_gethostbyname(own_host, &ip4, &ip6) == 0)
|
||||
save_ips(&ip4, &ip6, own_ip4, own_ip6);
|
||||
if (net_gethostbyname_first_ips(own_host, G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT,
|
||||
&ip4, &ip6) == 0)
|
||||
save_ips(&ip4, &ip6, own_ip4, own_ip6);
|
||||
}
|
||||
|
||||
server_connect_own_ip_save(conn, *own_ip4, *own_ip6);
|
||||
|
|
|
|||
|
|
@ -51,20 +51,16 @@ void server_connect_failed(SERVER_REC *server, const char *msg)
|
|||
g_source_remove(server->connect_tag);
|
||||
server->connect_tag = -1;
|
||||
}
|
||||
if (server->connect_cancellable != NULL) {
|
||||
g_cancellable_cancel(server->connect_cancellable);
|
||||
g_object_unref(server->connect_cancellable);
|
||||
server->connect_cancellable = NULL;
|
||||
}
|
||||
if (server->handle != NULL) {
|
||||
net_sendbuffer_destroy(server->handle, TRUE);
|
||||
server->handle = NULL;
|
||||
}
|
||||
|
||||
if (server->connect_pipe[0] != NULL) {
|
||||
g_io_channel_shutdown(server->connect_pipe[0], TRUE, NULL);
|
||||
g_io_channel_unref(server->connect_pipe[0]);
|
||||
g_io_channel_shutdown(server->connect_pipe[1], TRUE, NULL);
|
||||
g_io_channel_unref(server->connect_pipe[1]);
|
||||
server->connect_pipe[0] = NULL;
|
||||
server->connect_pipe[1] = NULL;
|
||||
}
|
||||
|
||||
server_unref(server);
|
||||
}
|
||||
|
||||
|
|
@ -156,7 +152,7 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
|
|||
error = net_geterror(handle);
|
||||
if (error != 0) {
|
||||
server->connection_lost = TRUE;
|
||||
server->connrec->last_failed_family = server->connrec->chosen_family;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
server_connect_failed(server, g_strerror(error));
|
||||
return;
|
||||
}
|
||||
|
|
@ -177,7 +173,7 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han
|
|||
error = irssi_ssl_handshake(handle);
|
||||
if (error == -1) {
|
||||
server->connection_lost = TRUE;
|
||||
server->connrec->last_failed_family = server->connrec->chosen_family;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
server_connect_failed(server, NULL);
|
||||
return;
|
||||
}
|
||||
|
|
@ -259,12 +255,12 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||
|
||||
server->connection_lost = TRUE;
|
||||
if (ip != NULL) {
|
||||
server->connrec->last_failed_family = ip->family;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
}
|
||||
server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
|
||||
g_free(errmsg2);
|
||||
} else {
|
||||
server->connrec->last_failed_family = 0;
|
||||
server->connrec->last_failed = 0;
|
||||
if (!server->connrec->use_tls)
|
||||
server->handle = net_sendbuffer_create(handle, 0);
|
||||
if (server->connrec->use_tls)
|
||||
|
|
@ -276,48 +272,47 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||
}
|
||||
}
|
||||
|
||||
static void server_connect_callback_readpipe(SERVER_REC *server)
|
||||
static int server_start_connect_resolve(SERVER_REC *server);
|
||||
|
||||
static void server_connect_use_resolved(SERVER_REC *server)
|
||||
{
|
||||
RESOLVED_IP_REC iprec;
|
||||
IPADDR *ip;
|
||||
IPADDR *ip;
|
||||
const char *errormsg;
|
||||
RESOLVED_IP_REC *iprec = server->connrec->resolved_host;
|
||||
|
||||
g_source_remove(server->connect_tag);
|
||||
server->connect_tag = -1;
|
||||
|
||||
net_gethostbyname_return(server->connect_pipe[0], &iprec);
|
||||
|
||||
g_io_channel_shutdown(server->connect_pipe[0], TRUE, NULL);
|
||||
g_io_channel_unref(server->connect_pipe[0]);
|
||||
g_io_channel_shutdown(server->connect_pipe[1], TRUE, NULL);
|
||||
g_io_channel_unref(server->connect_pipe[1]);
|
||||
|
||||
server->connect_pipe[0] = NULL;
|
||||
server->connect_pipe[1] = NULL;
|
||||
|
||||
/* figure out if we should use IPv4 or v6 address */
|
||||
if (iprec.error != 0) {
|
||||
/* error */
|
||||
if (iprec->error != NULL) {
|
||||
/* error */
|
||||
ip = NULL;
|
||||
} else if (server->connrec->family == AF_INET) {
|
||||
/* force IPv4 connection */
|
||||
ip = iprec.ip4.family == 0 ? NULL : &iprec.ip4;
|
||||
} else if (server->connrec->family == AF_INET6) {
|
||||
/* force IPv6 connection */
|
||||
ip = iprec.ip6.family == 0 ? NULL : &iprec.ip6;
|
||||
} else {
|
||||
/* pick the one that was found. if both were found:
|
||||
1. disprefer the last one that failed
|
||||
2. prefer ipv4 over ipv6 unless resolve_prefer_ipv6 is set
|
||||
*/
|
||||
if (iprec.ip4.family == 0 ||
|
||||
(iprec.ip6.family != 0 &&
|
||||
(server->connrec->last_failed_family == AF_INET ||
|
||||
(settings_get_bool("resolve_prefer_ipv6") &&
|
||||
server->connrec->last_failed_family != AF_INET6)))) {
|
||||
ip = &iprec.ip6;
|
||||
GList *curr;
|
||||
int i;
|
||||
|
||||
curr = iprec->ailist;
|
||||
i = 0;
|
||||
while (i < server->connrec->last_failed) {
|
||||
if (curr != NULL) {
|
||||
curr = curr->next;
|
||||
i++;
|
||||
}
|
||||
/* curr is different now */
|
||||
if (curr == NULL) {
|
||||
resolved_ip_unref(server->connrec->resolved_host);
|
||||
server->connrec->resolved_host = NULL;
|
||||
server->connrec->last_failed = 0;
|
||||
/* retry resolve */
|
||||
server_start_connect_resolve(server);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (curr != NULL) {
|
||||
GInetAddress *addr;
|
||||
addr = curr->data;
|
||||
server->connrec->last_connected = i + 1;
|
||||
ip = g_new0(IPADDR, 1);
|
||||
ip->family = g_inet_address_get_family(addr);
|
||||
memcpy(&ip->ip, g_inet_address_to_bytes(addr), sizeof(ip->ip));
|
||||
} else {
|
||||
ip = &iprec.ip4;
|
||||
ip = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -326,28 +321,63 @@ static void server_connect_callback_readpipe(SERVER_REC *server)
|
|||
server_real_connect(server, ip, NULL);
|
||||
errormsg = NULL;
|
||||
} else {
|
||||
if (iprec.error == 0 || net_hosterror_notfound(iprec.error)) {
|
||||
if (iprec->error->code == G_RESOLVER_ERROR_NOT_FOUND) {
|
||||
/* IP wasn't found for the host, don't try to
|
||||
reconnect back to this server */
|
||||
server->dns_error = TRUE;
|
||||
}
|
||||
|
||||
if (iprec.error == 0) {
|
||||
/* forced IPv4 or IPv6 address but it wasn't found */
|
||||
errormsg = server->connrec->family == AF_INET ?
|
||||
"IPv4 address not found for host" :
|
||||
"IPv6 address not found for host";
|
||||
} else {
|
||||
/* gethostbyname() failed */
|
||||
errormsg = iprec.errorstr != NULL ? iprec.errorstr :
|
||||
"Host lookup failed";
|
||||
}
|
||||
errormsg = iprec->error->message;
|
||||
if (errormsg == NULL)
|
||||
errormsg = "Host lookup failed";
|
||||
|
||||
server->connection_lost = TRUE;
|
||||
/* clear the error in resolved_host */
|
||||
server->connrec->resolved_host = NULL;
|
||||
server_connect_failed(server, errormsg);
|
||||
}
|
||||
|
||||
g_free(iprec.errorstr);
|
||||
resolved_ip_unref(iprec);
|
||||
}
|
||||
}
|
||||
|
||||
static void server_connect_callback_resolved(RESOLVED_IP_REC *iprec, SERVER_REC *server)
|
||||
{
|
||||
server->connect_cancellable = NULL;
|
||||
|
||||
if (server->connrec->resolved_host != NULL) {
|
||||
resolved_ip_unref(server->connrec->resolved_host);
|
||||
}
|
||||
server->connrec->resolved_host = iprec;
|
||||
if (iprec->error == NULL && iprec->ailist == NULL) {
|
||||
server->connection_lost = TRUE;
|
||||
server->dns_error = TRUE;
|
||||
server_connect_failed(server, "Host lookup failed");
|
||||
} else {
|
||||
server_connect_use_resolved(server);
|
||||
}
|
||||
}
|
||||
|
||||
static int server_start_connect_resolve(SERVER_REC *server)
|
||||
{
|
||||
const char *connect_address;
|
||||
GResolverNameLookupFlags net_gethostbyname_flags;
|
||||
|
||||
connect_address =
|
||||
server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->address;
|
||||
net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT;
|
||||
if (server->connrec->family == AF_INET) {
|
||||
net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_IPV4_ONLY;
|
||||
} else if (server->connrec->family == AF_INET6) {
|
||||
net_gethostbyname_flags = G_RESOLVER_NAME_LOOKUP_FLAGS_IPV6_ONLY;
|
||||
}
|
||||
if (server->connrec->resolved_host == NULL) {
|
||||
server->connect_cancellable = net_gethostbyname_nonblock(
|
||||
connect_address, net_gethostbyname_flags,
|
||||
(NetGethostbynameContinuationFunc) server_connect_callback_resolved, server);
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
SERVER_REC *server_connect(SERVER_CONNECT_REC *conn)
|
||||
|
|
@ -399,9 +429,6 @@ void server_connect_init(SERVER_REC *server)
|
|||
/* starts connecting to server */
|
||||
int server_start_connect(SERVER_REC *server)
|
||||
{
|
||||
const char *connect_address;
|
||||
int fd[2];
|
||||
|
||||
g_return_val_if_fail(server != NULL, FALSE);
|
||||
if (!server->connrec->unix_socket && server->connrec->port <= 0)
|
||||
return FALSE;
|
||||
|
|
@ -419,30 +446,17 @@ int server_start_connect(SERVER_REC *server)
|
|||
/* connect with unix socket */
|
||||
server_real_connect(server, NULL, server->connrec->address);
|
||||
} else {
|
||||
int already_resolved;
|
||||
/* resolve host name */
|
||||
if (pipe(fd) != 0) {
|
||||
g_warning("server_connect(): pipe() failed.");
|
||||
g_free(server->tag);
|
||||
g_free(server->nick);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
server->connect_pipe[0] = i_io_channel_new(fd[0]);
|
||||
server->connect_pipe[1] = i_io_channel_new(fd[1]);
|
||||
|
||||
connect_address = server->connrec->proxy != NULL ?
|
||||
server->connrec->proxy : server->connrec->address;
|
||||
server->connect_pid =
|
||||
net_gethostbyname_nonblock(connect_address,
|
||||
server->connect_pipe[1], 0);
|
||||
server->connect_tag =
|
||||
i_input_add(server->connect_pipe[0], I_INPUT_READ,
|
||||
(GInputFunction) server_connect_callback_readpipe, server);
|
||||
already_resolved = server_start_connect_resolve(server);
|
||||
|
||||
server->connect_time = time(NULL);
|
||||
lookup_servers = g_slist_append(lookup_servers, server);
|
||||
|
||||
signal_emit("server looking", 1, server);
|
||||
if (already_resolved) {
|
||||
server_connect_use_resolved(server);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -481,8 +495,9 @@ void server_disconnect(SERVER_REC *server)
|
|||
|
||||
if (server->connect_tag != -1) {
|
||||
/* still connecting to server.. */
|
||||
if (server->connect_pid != -1)
|
||||
net_disconnect_nonblock(server->connect_pid);
|
||||
server_connect_failed(server, NULL);
|
||||
return;
|
||||
} else if (server->connect_cancellable != NULL) {
|
||||
server_connect_failed(server, NULL);
|
||||
return;
|
||||
}
|
||||
|
|
@ -649,6 +664,10 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
|
|||
g_free_not_null(conn->own_ip4);
|
||||
g_free_not_null(conn->own_ip6);
|
||||
|
||||
if (conn->resolved_host != NULL) {
|
||||
resolved_ip_unref(conn->resolved_host);
|
||||
}
|
||||
|
||||
g_free_not_null(conn->password);
|
||||
g_free_not_null(conn->nick);
|
||||
g_free_not_null(conn->username);
|
||||
|
|
@ -769,7 +788,6 @@ static void sig_chat_protocol_deinit(CHAT_PROTOCOL_REC *proto)
|
|||
|
||||
void servers_init(void)
|
||||
{
|
||||
settings_add_bool("server", "resolve_prefer_ipv6", TRUE);
|
||||
lookup_servers = servers = NULL;
|
||||
|
||||
signal_add("chat protocol deinit", (SIGNAL_FUNC) sig_chat_protocol_deinit);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define IRSSI_CORE_SERVERS_H
|
||||
|
||||
#include <irssi/src/core/modules.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
|
||||
/* Returns SERVER_REC if it's server, NULL if it isn't. */
|
||||
#define SERVER(server) \
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ void fe_common_core_init(void)
|
|||
settings_add_bool("lookandfeel", "use_msgs_window", FALSE);
|
||||
g_get_charset(&str);
|
||||
settings_add_str("lookandfeel", "term_charset", str);
|
||||
settings_add_str("lookandfeel", "glib_log_domains", "all");
|
||||
settings_add_str("lookandfeel", "glib_log_domains", "all -glib-gio:debug");
|
||||
themes_init();
|
||||
theme_register(fecommon_core_formats);
|
||||
|
||||
|
|
@ -258,13 +258,19 @@ void fe_common_core_deinit(void)
|
|||
g_log_set_default_handler(logger_old, NULL);
|
||||
}
|
||||
|
||||
static gboolean glib_domain_wanted(const char *domain)
|
||||
static gboolean glib_domain_wanted(const char *domain, const char *level)
|
||||
{
|
||||
const char *domains;
|
||||
char *c, *cur;
|
||||
int len = 0;
|
||||
int print_it = 0; /* -1 for exclude, 0 for undecided, 1 for include */
|
||||
int incl;
|
||||
char *domainlevel, *alllevel, *starlevel, *domainstar;
|
||||
|
||||
domainlevel = g_strdup_printf("%s:%s", domain, level);
|
||||
alllevel = g_strdup_printf("all:%s", level);
|
||||
starlevel = g_strdup_printf("*:%s", level);
|
||||
domainstar = g_strdup_printf("%s:*", domain);
|
||||
|
||||
/* Go through each item in glib_log_domains setting to determine whether
|
||||
* or not we want to print message from this domain */
|
||||
|
|
@ -287,8 +293,10 @@ static gboolean glib_domain_wanted(const char *domain)
|
|||
}
|
||||
|
||||
/* If we got a valid item, process it */
|
||||
if (len > 0 && (!strncmp(domain, c, len) || !strncasecmp("all", c, len) ||
|
||||
!strncmp("*", c, len)))
|
||||
if (len > 0 && (!strncasecmp(domain, c, len) || !strncasecmp("all", c, len) ||
|
||||
!strncmp("*", c, len) || !strncasecmp(domainstar, c, len) ||
|
||||
!strncasecmp(domainlevel, c, len) ||
|
||||
!strncasecmp(alllevel, c, len) || !strncasecmp(starlevel, c, len)))
|
||||
print_it = incl;
|
||||
|
||||
/* Go past any spaces towards the next item */
|
||||
|
|
@ -300,6 +308,11 @@ static gboolean glib_domain_wanted(const char *domain)
|
|||
len = 0;
|
||||
} while (*c != '\0' && print_it != -1);
|
||||
|
||||
g_free(domainlevel);
|
||||
g_free(alllevel);
|
||||
g_free(starlevel);
|
||||
g_free(domainstar);
|
||||
|
||||
return (print_it == 1);
|
||||
}
|
||||
|
||||
|
|
@ -333,7 +346,7 @@ static void i_log_func(const char *log_domain, GLogLevelFlags log_level, const c
|
|||
domain = (log_domain ? log_domain : "default");
|
||||
|
||||
/* Only print the message if we decided to */
|
||||
if (!glib_domain_wanted(domain))
|
||||
if (!glib_domain_wanted(domain, reason))
|
||||
return;
|
||||
|
||||
if (windows == NULL)
|
||||
|
|
|
|||
|
|
@ -711,16 +711,19 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path)
|
|||
/* bind to specific host/ip? */
|
||||
my_ip = NULL;
|
||||
if (*settings_get_str("irssiproxy_bind") != '\0') {
|
||||
if (net_gethostbyname(settings_get_str("irssiproxy_bind"),
|
||||
&ip4, &ip6) != 0) {
|
||||
if (net_gethostbyname_first_ips(settings_get_str("irssiproxy_bind"),
|
||||
G_RESOLVER_NAME_LOOKUP_FLAGS_DEFAULT, &ip4,
|
||||
&ip6) != 0) {
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
|
||||
"Proxy: can not resolve '%s' - aborting",
|
||||
settings_get_str("irssiproxy_bind"));
|
||||
return;
|
||||
}
|
||||
|
||||
my_ip = ip6.family == 0 ? &ip4 : ip4.family == 0 ||
|
||||
settings_get_bool("resolve_prefer_ipv6") ? &ip6 : &ip4;
|
||||
my_ip = ip6.family == 0 ? &ip4 :
|
||||
ip4.family == 0 || settings_get_bool("irssiproxy_prefer_ipv6") ?
|
||||
&ip6 :
|
||||
&ip4;
|
||||
}
|
||||
handle = net_listen(my_ip, &port);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ static void irc_proxy_setup_changed(void)
|
|||
|
||||
void irc_proxy_init(void)
|
||||
{
|
||||
settings_add_bool("irssiproxy", "irssiproxy_prefer_ipv6", TRUE);
|
||||
settings_add_str("irssiproxy", "irssiproxy_ports", "");
|
||||
settings_add_str("irssiproxy", "irssiproxy_password", "");
|
||||
settings_add_str("irssiproxy", "irssiproxy_bind", "");
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[wrap-file]
|
||||
# make sure to update the glib_internal_version in meson.build
|
||||
directory = glib-2.74.3
|
||||
source_url = https://download.gnome.org/sources/glib/2.74/glib-2.74.3.tar.xz
|
||||
source_filename = glib-2.74.3.tar.xz
|
||||
source_hash = e9bc41ecd9690d9bc6a970cc7380119b828e5b6a4b16c393c638b3dc2b87cbcb
|
||||
directory = glib-2.74.7
|
||||
source_url = https://download.gnome.org/sources/glib/2.74/glib-2.74.7.tar.xz
|
||||
source_filename = glib-2.74.7.tar.xz
|
||||
source_hash = 196ab86c27127a61b7a70c3ba6af7b97bdc01c07cd3b21abd5e778b955eccb1b
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue