mirror of
https://github.com/irssi/irssi.git
synced 2026-08-08 19:30:15 +02:00
Merge 571599f673 into 43f1727ef9
This commit is contained in:
commit
0196405384
22 changed files with 712 additions and 337 deletions
|
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include <irssi/src/core/net-sendbuffer.h>
|
||||
#include <irssi/src/core/network.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
|
|
@ -31,7 +32,8 @@
|
|||
|
||||
typedef struct {
|
||||
time_t created;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
GIOStream *stream;
|
||||
int tag;
|
||||
} NET_DISCONNECT_REC;
|
||||
|
||||
|
|
@ -39,12 +41,21 @@ static GSList *disconnects;
|
|||
|
||||
static int timeout_tag;
|
||||
|
||||
void net_disconnect_any(NET_DISCONNECT_REC *rec)
|
||||
{
|
||||
if (rec->channel != NULL)
|
||||
net_disconnect_channel(rec->channel);
|
||||
else
|
||||
net_disconnect_stream(rec->stream);
|
||||
}
|
||||
|
||||
static void net_disconnect_remove(NET_DISCONNECT_REC *rec)
|
||||
{
|
||||
g_warning("disconnect finished");
|
||||
disconnects = g_slist_remove(disconnects, rec);
|
||||
|
||||
g_source_remove(rec->tag);
|
||||
net_disconnect(rec->handle);
|
||||
net_disconnect_any(rec);
|
||||
g_free(rec);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +68,7 @@ static void sig_disconnect(NET_DISCONNECT_REC *rec)
|
|||
if server just keeps sending us stuff we won't get stuck */
|
||||
count = 0;
|
||||
do {
|
||||
ret = net_receive(rec->handle, buf, sizeof(buf));
|
||||
ret = net_receive_channel(rec->channel, buf, sizeof(buf));
|
||||
if (ret == -1) {
|
||||
/* socket was closed */
|
||||
net_disconnect_remove(rec);
|
||||
|
|
@ -66,6 +77,35 @@ static void sig_disconnect(NET_DISCONNECT_REC *rec)
|
|||
} while (ret == sizeof(buf) && count < 18);
|
||||
}
|
||||
|
||||
// static gboolean sig_disconnect_source(GObject *pollable_stream, NET_DISCONNECT_REC *rec)
|
||||
static gboolean sig_disconnect_source(GSocket *socket, GIOCondition cond, NET_DISCONNECT_REC *rec)
|
||||
{
|
||||
char buf[512];
|
||||
int count, ret;
|
||||
|
||||
g_warning("sig_disconnect_source, condition: %d", cond);
|
||||
|
||||
if (cond & (G_IO_ERR | G_IO_HUP)) {
|
||||
net_disconnect_remove(rec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* check if there's any data waiting in socket. read max. 9kB so
|
||||
if server just keeps sending us stuff we won't get stuck */
|
||||
count = 0;
|
||||
do {
|
||||
ret = net_receive_stream(rec->stream, buf, sizeof(buf));
|
||||
if (ret == -1) {
|
||||
/* socket was closed */
|
||||
net_disconnect_remove(rec);
|
||||
return FALSE;
|
||||
}
|
||||
count++;
|
||||
} while (ret == sizeof(buf) && count < 18);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int sig_timeout_disconnect(void)
|
||||
{
|
||||
NET_DISCONNECT_REC *rec;
|
||||
|
|
@ -92,15 +132,32 @@ static int sig_timeout_disconnect(void)
|
|||
|
||||
/* Try to let the other side close the connection, if it still isn't
|
||||
disconnected after certain amount of time, close it ourself */
|
||||
void net_disconnect_later(GIOChannel *handle)
|
||||
void net_disconnect_later(NET_SENDBUF_REC *handle)
|
||||
{
|
||||
NET_DISCONNECT_REC *rec;
|
||||
|
||||
rec = g_new(NET_DISCONNECT_REC, 1);
|
||||
rec->created = time(NULL);
|
||||
rec->handle = handle;
|
||||
rec->tag = i_input_add(handle, I_INPUT_READ, (GInputFunction) sig_disconnect, rec);
|
||||
if (handle->channel != NULL) {
|
||||
rec->channel = handle->channel;
|
||||
rec->tag =
|
||||
i_input_add(rec->channel, I_INPUT_READ, (GInputFunction) sig_disconnect, rec);
|
||||
} else if (handle->stream != NULL) {
|
||||
// GInputStream *in;
|
||||
GSocket *socket;
|
||||
GSource *source;
|
||||
|
||||
socket = g_socket_connection_get_socket((GSocketConnection *) handle->stream);
|
||||
source = g_socket_create_source(socket, G_IO_IN | G_IO_HUP, NULL);
|
||||
// in = g_io_stream_get_input_stream((GIOStream *) rec->stream);
|
||||
// source = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(in),
|
||||
// NULL);
|
||||
g_source_set_callback(source, G_SOURCE_FUNC(sig_disconnect_source), rec, NULL);
|
||||
rec->stream = handle->stream;
|
||||
rec->tag = g_source_attach(source, NULL);
|
||||
g_warning("net_disconnect_rec.tag: %d", rec->tag);
|
||||
// TODO
|
||||
}
|
||||
if (timeout_tag == -1) {
|
||||
timeout_tag = g_timeout_add(10000, (GSourceFunc)
|
||||
sig_timeout_disconnect, NULL);
|
||||
|
|
@ -136,15 +193,27 @@ void net_disconnect_deinit(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
fd = g_io_channel_unix_get_fd(rec->handle);
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
tv.tv_sec = first ? 0 : max-now;
|
||||
tv.tv_usec = first ? 100000 : 0;
|
||||
if (select(fd+1, &set, NULL, NULL, &tv) > 0 &&
|
||||
FD_ISSET(fd, &set)) {
|
||||
/* data coming .. check if we can close the handle */
|
||||
sig_disconnect(rec);
|
||||
if (rec->channel != NULL) {
|
||||
fd = g_io_channel_unix_get_fd(rec->channel);
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
tv.tv_sec = first ? 0 : max - now;
|
||||
tv.tv_usec = first ? 100000 : 0;
|
||||
if (select(fd + 1, &set, NULL, NULL, &tv) > 0 && FD_ISSET(fd, &set)) {
|
||||
/* data coming .. check if we can close the handle */
|
||||
sig_disconnect(rec);
|
||||
}
|
||||
} else if (rec->stream != NULL) {
|
||||
// TODO! timeouts
|
||||
/* GInputStream *iin; */
|
||||
/* GPollableInputStream *in; */
|
||||
|
||||
/* iin = g_io_stream_get_input_stream(rec->stream); */
|
||||
/* in = G_POLLABLE_INPUT_STREAM(iin); */
|
||||
/* if (g_pollable_input_stream_is_readable(in)) { */
|
||||
/* (void)sig_disconnect_source(g_socket_connection_get_socket((GSocketConnection
|
||||
* *)rec->stream), G_IO_IN, rec); */
|
||||
/* } */
|
||||
} else if (first) {
|
||||
/* Display the text when we have already waited
|
||||
for a while */
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#ifndef IRSSI_CORE_NET_DISCONNECT_H
|
||||
#define IRSSI_CORE_NET_DISCONNECT_H
|
||||
|
||||
#include <irssi/src/common.h>
|
||||
|
||||
/* Try to let the other side close the connection, if it still isn't
|
||||
disconnected after certain amount of time, close it ourself */
|
||||
void net_disconnect_later(GIOChannel *handle);
|
||||
void net_disconnect_later(NET_SENDBUF_REC *handle);
|
||||
|
||||
void net_disconnect_init(void);
|
||||
void net_disconnect_deinit(void);
|
||||
|
|
|
|||
|
|
@ -26,15 +26,30 @@
|
|||
|
||||
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
||||
is used */
|
||||
NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize)
|
||||
NET_SENDBUF_REC *net_sendbuffer_create_channel(GIOChannel *channel, int bufsize)
|
||||
{
|
||||
NET_SENDBUF_REC *rec;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, NULL);
|
||||
g_return_val_if_fail(channel != NULL, NULL);
|
||||
|
||||
rec = g_new0(NET_SENDBUF_REC, 1);
|
||||
rec->send_tag = -1;
|
||||
rec->handle = handle;
|
||||
rec->channel = channel;
|
||||
rec->bufsize = bufsize > 0 ? bufsize : DEFAULT_BUFFER_SIZE;
|
||||
rec->def_bufsize = rec->bufsize;
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
NET_SENDBUF_REC *net_sendbuffer_create_stream(GIOStream *stream, int bufsize)
|
||||
{
|
||||
NET_SENDBUF_REC *rec;
|
||||
|
||||
g_return_val_if_fail(stream != NULL, NULL);
|
||||
|
||||
rec = g_new0(NET_SENDBUF_REC, 1);
|
||||
rec->send_tag = -1;
|
||||
rec->stream = stream;
|
||||
rec->bufsize = bufsize > 0 ? bufsize : DEFAULT_BUFFER_SIZE;
|
||||
rec->def_bufsize = rec->bufsize;
|
||||
|
||||
|
|
@ -45,8 +60,15 @@ NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize)
|
|||
void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close)
|
||||
{
|
||||
if (rec->send_tag != -1) g_source_remove(rec->send_tag);
|
||||
if (close) net_disconnect(rec->handle);
|
||||
if (close) {
|
||||
if (rec->channel != NULL)
|
||||
net_disconnect_channel(rec->channel);
|
||||
else
|
||||
net_disconnect_stream(rec->stream);
|
||||
}
|
||||
if (rec->readbuffer != NULL) line_split_free(rec->readbuffer);
|
||||
if (rec->stream != NULL)
|
||||
g_object_unref(rec->stream);
|
||||
g_free_not_null(rec->buffer);
|
||||
g_free(rec);
|
||||
}
|
||||
|
|
@ -56,7 +78,7 @@ static int buffer_send(NET_SENDBUF_REC *rec)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = net_transmit(rec->handle, rec->buffer, rec->bufpos);
|
||||
ret = net_transmit_channel(rec->channel, rec->buffer, rec->bufpos);
|
||||
if (ret < 0 || rec->bufpos == ret) {
|
||||
/* error/all sent - don't try to send it anymore */
|
||||
rec->bufsize = rec->def_bufsize;
|
||||
|
|
@ -83,6 +105,14 @@ static void sig_sendbuffer(NET_SENDBUF_REC *rec)
|
|||
rec->send_tag = -1;
|
||||
}
|
||||
|
||||
static gboolean sig_sendbuffer_source(GObject *pollable_stream, NET_SENDBUF_REC *rec)
|
||||
{
|
||||
g_warning("sig_sendbuffer_source");
|
||||
|
||||
sig_sendbuffer(rec);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Add `data' to transmit buffer - return FALSE if buffer is full */
|
||||
static int buffer_add(NET_SENDBUF_REC *rec, const void *data, int size)
|
||||
{
|
||||
|
|
@ -102,7 +132,7 @@ static int buffer_add(NET_SENDBUF_REC *rec, const void *data, int size)
|
|||
rec->buffer = g_realloc(rec->buffer, rec->bufsize);
|
||||
}
|
||||
|
||||
memcpy(rec->buffer+rec->bufpos, data, size);
|
||||
memcpy(rec->buffer + rec->bufpos, data, size);
|
||||
rec->bufpos += size;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -112,7 +142,7 @@ static int buffer_add(NET_SENDBUF_REC *rec, const void *data, int size)
|
|||
occurred. */
|
||||
int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
g_return_val_if_fail(rec != NULL, -1);
|
||||
g_return_val_if_fail(data != NULL, -1);
|
||||
|
|
@ -120,7 +150,10 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
|
|||
|
||||
if (rec->buffer == NULL || rec->bufpos == 0) {
|
||||
/* nothing in buffer - transmit immediately */
|
||||
ret = net_transmit(rec->handle, data, size);
|
||||
if (rec->channel != NULL)
|
||||
ret = net_transmit_channel(rec->channel, data, size);
|
||||
else if (rec->stream != NULL)
|
||||
ret = net_transmit_stream(rec->stream, data, size);
|
||||
if (ret < 0) return -1;
|
||||
size -= ret;
|
||||
data = ((const char *) data) + ret;
|
||||
|
|
@ -131,8 +164,21 @@ int net_sendbuffer_send(NET_SENDBUF_REC *rec, const void *data, int size)
|
|||
|
||||
/* everything couldn't be sent. */
|
||||
if (rec->send_tag == -1) {
|
||||
rec->send_tag =
|
||||
i_input_add(rec->handle, I_INPUT_WRITE, (GInputFunction) sig_sendbuffer, rec);
|
||||
if (rec->channel != NULL) {
|
||||
rec->send_tag = i_input_add(rec->channel, I_INPUT_WRITE,
|
||||
(GInputFunction) sig_sendbuffer, rec);
|
||||
} else if (rec->stream != NULL) {
|
||||
GOutputStream *out;
|
||||
GSource *source;
|
||||
|
||||
out = g_io_stream_get_output_stream(rec->stream);
|
||||
source = g_pollable_output_stream_create_source(
|
||||
G_POLLABLE_OUTPUT_STREAM(out), NULL);
|
||||
g_source_set_callback(source, G_SOURCE_FUNC(sig_sendbuffer_source), rec,
|
||||
NULL);
|
||||
rec->send_tag = g_source_attach(source, NULL);
|
||||
g_warning("send_tag: %d", rec->send_tag);
|
||||
}
|
||||
}
|
||||
|
||||
return buffer_add(rec, data, size) ? 0 : -1;
|
||||
|
|
@ -143,8 +189,12 @@ int net_sendbuffer_receive_line(NET_SENDBUF_REC *rec, char **str, int read_socke
|
|||
char tmpbuf[2048];
|
||||
int recvlen = 0;
|
||||
|
||||
if (read_socket)
|
||||
recvlen = net_receive(rec->handle, tmpbuf, sizeof(tmpbuf));
|
||||
if (read_socket) {
|
||||
if (rec->channel != NULL)
|
||||
recvlen = net_receive_channel(rec->channel, tmpbuf, sizeof(tmpbuf));
|
||||
else if (rec->stream != NULL)
|
||||
recvlen = net_receive_stream(rec->stream, tmpbuf, sizeof(tmpbuf));
|
||||
}
|
||||
|
||||
return line_split(tmpbuf, recvlen, str, &rec->readbuffer);
|
||||
}
|
||||
|
|
@ -158,16 +208,16 @@ void net_sendbuffer_flush(NET_SENDBUF_REC *rec)
|
|||
return;
|
||||
|
||||
/* set the socket blocking while doing this */
|
||||
handle = g_io_channel_unix_get_fd(rec->handle);
|
||||
handle = g_io_channel_unix_get_fd(rec->channel);
|
||||
fcntl(handle, F_SETFL, 0);
|
||||
while (!buffer_send(rec)) ;
|
||||
fcntl(handle, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
/* Returns the socket handle */
|
||||
GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec)
|
||||
GIOChannel *net_sendbuffer_channel(NET_SENDBUF_REC *rec)
|
||||
{
|
||||
g_return_val_if_fail(rec != NULL, NULL);
|
||||
|
||||
return rec->handle;
|
||||
return rec->channel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,30 @@
|
|||
#ifndef IRSSI_CORE_NET_SENDBUFFER_H
|
||||
#define IRSSI_CORE_NET_SENDBUFFER_H
|
||||
|
||||
#include <irssi/src/common.h>
|
||||
|
||||
#define DEFAULT_BUFFER_SIZE 8192
|
||||
#define MAX_BUFFER_SIZE 1048576
|
||||
|
||||
struct _NET_SENDBUF_REC {
|
||||
GIOChannel *handle;
|
||||
LINEBUF_REC *readbuffer; /* receive buffer */
|
||||
GIOChannel *channel;
|
||||
GIOStream *stream;
|
||||
LINEBUF_REC *readbuffer; /* receive buffer */
|
||||
|
||||
int send_tag;
|
||||
int bufsize;
|
||||
int bufpos;
|
||||
char *buffer; /* Buffer is NULL until it's actually needed. */
|
||||
int def_bufsize;
|
||||
unsigned int dead:1;
|
||||
int send_tag;
|
||||
int bufsize;
|
||||
int bufpos;
|
||||
char *buffer; /* Buffer is NULL until it's actually needed. */
|
||||
int def_bufsize;
|
||||
unsigned int dead : 1;
|
||||
};
|
||||
|
||||
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
||||
is used */
|
||||
NET_SENDBUF_REC *net_sendbuffer_create(GIOChannel *handle, int bufsize);
|
||||
NET_SENDBUF_REC *net_sendbuffer_create_channel(GIOChannel *channel, int bufsize);
|
||||
/* Create new buffer - if `bufsize' is zero or less, DEFAULT_BUFFER_SIZE
|
||||
is used */
|
||||
NET_SENDBUF_REC *net_sendbuffer_create_stream(GIOStream *stream, int bufsize);
|
||||
/* Destroy the buffer. `close' specifies if socket handle should be closed. */
|
||||
void net_sendbuffer_destroy(NET_SENDBUF_REC *rec, int close);
|
||||
|
||||
|
|
@ -33,6 +39,6 @@ int net_sendbuffer_receive_line(NET_SENDBUF_REC *rec, char **str, int read_socke
|
|||
void net_sendbuffer_flush(NET_SENDBUF_REC *rec);
|
||||
|
||||
/* Returns the socket handle */
|
||||
GIOChannel *net_sendbuffer_handle(NET_SENDBUF_REC *rec);
|
||||
GIOChannel *net_sendbuffer_channel(NET_SENDBUF_REC *rec);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ static int ssl_inited = FALSE;
|
|||
static X509_STORE *store = NULL;
|
||||
#endif
|
||||
|
||||
static void irssi_ssl_free(GIOChannel *handle)
|
||||
static void irssi_ssl_free(GIOChannel *channel)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
g_io_channel_unref(chan->giochan);
|
||||
SSL_free(chan->ssl);
|
||||
SSL_CTX_free(chan->ctx);
|
||||
|
|
@ -247,9 +247,10 @@ static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, i
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static GIOStatus irssi_ssl_read(GIOChannel *handle, gchar *buf, gsize len, gsize *ret, GError **gerr)
|
||||
static GIOStatus irssi_ssl_read(GIOChannel *channel, gchar *buf, gsize len, gsize *ret,
|
||||
GError **gerr)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
gint ret1, err;
|
||||
const char *errstr;
|
||||
gchar *errmsg;
|
||||
|
|
@ -293,9 +294,10 @@ static GIOStatus irssi_ssl_read(GIOChannel *handle, gchar *buf, gsize len, gsize
|
|||
return G_IO_STATUS_ERROR;
|
||||
}
|
||||
|
||||
static GIOStatus irssi_ssl_write(GIOChannel *handle, const gchar *buf, gsize len, gsize *ret, GError **gerr)
|
||||
static GIOStatus irssi_ssl_write(GIOChannel *channel, const gchar *buf, gsize len, gsize *ret,
|
||||
GError **gerr)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
gint ret1, err;
|
||||
const char *errstr;
|
||||
gchar *errmsg;
|
||||
|
|
@ -339,39 +341,39 @@ static GIOStatus irssi_ssl_write(GIOChannel *handle, const gchar *buf, gsize len
|
|||
return G_IO_STATUS_ERROR;
|
||||
}
|
||||
|
||||
static GIOStatus irssi_ssl_seek(GIOChannel *handle, gint64 offset, GSeekType type, GError **gerr)
|
||||
static GIOStatus irssi_ssl_seek(GIOChannel *channel, gint64 offset, GSeekType type, GError **gerr)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
|
||||
return chan->giochan->funcs->io_seek(handle, offset, type, gerr);
|
||||
return chan->giochan->funcs->io_seek(channel, offset, type, gerr);
|
||||
}
|
||||
|
||||
static GIOStatus irssi_ssl_close(GIOChannel *handle, GError **gerr)
|
||||
static GIOStatus irssi_ssl_close(GIOChannel *channel, GError **gerr)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
|
||||
return chan->giochan->funcs->io_close(handle, gerr);
|
||||
return chan->giochan->funcs->io_close(channel, gerr);
|
||||
}
|
||||
|
||||
static GSource *irssi_ssl_create_watch(GIOChannel *handle, GIOCondition cond)
|
||||
static GSource *irssi_ssl_create_watch(GIOChannel *channel, GIOCondition cond)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
|
||||
return chan->giochan->funcs->io_create_watch(handle, cond);
|
||||
return chan->giochan->funcs->io_create_watch(channel, cond);
|
||||
}
|
||||
|
||||
static GIOStatus irssi_ssl_set_flags(GIOChannel *handle, GIOFlags flags, GError **gerr)
|
||||
static GIOStatus irssi_ssl_set_flags(GIOChannel *channel, GIOFlags flags, GError **gerr)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
|
||||
return chan->giochan->funcs->io_set_flags(handle, flags, gerr);
|
||||
return chan->giochan->funcs->io_set_flags(channel, flags, gerr);
|
||||
}
|
||||
|
||||
static GIOFlags irssi_ssl_get_flags(GIOChannel *handle)
|
||||
static GIOFlags irssi_ssl_get_flags(GIOChannel *channel)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
|
||||
return chan->giochan->funcs->io_get_flags(handle);
|
||||
return chan->giochan->funcs->io_get_flags(channel);
|
||||
}
|
||||
|
||||
static GIOFuncs irssi_ssl_channel_funcs = {
|
||||
|
|
@ -441,7 +443,7 @@ static int get_pem_password_callback(char *buffer, int max_length, int rwflag, v
|
|||
return length;
|
||||
}
|
||||
|
||||
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
|
||||
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *channel, int port, SERVER_REC *server)
|
||||
{
|
||||
GIOSSLChannel *chan;
|
||||
GIOChannel *gchan;
|
||||
|
|
@ -457,12 +459,12 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_
|
|||
const char *ciphers = server->connrec->tls_ciphers;
|
||||
gboolean verify = server->connrec->tls_verify;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, NULL);
|
||||
g_return_val_if_fail(channel != NULL, NULL);
|
||||
|
||||
if(!ssl_inited && !irssi_ssl_init())
|
||||
return NULL;
|
||||
|
||||
if(!(fd = g_io_channel_unix_get_fd(handle)))
|
||||
if (!(fd = g_io_channel_unix_get_fd(channel)))
|
||||
return NULL;
|
||||
|
||||
ERR_clear_error();
|
||||
|
|
@ -575,7 +577,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_
|
|||
|
||||
chan = g_new0(GIOSSLChannel, 1);
|
||||
chan->fd = fd;
|
||||
chan->giochan = handle;
|
||||
chan->giochan = channel;
|
||||
chan->ssl = ssl;
|
||||
chan->ctx = ctx;
|
||||
chan->server = server;
|
||||
|
|
@ -802,37 +804,36 @@ static void set_server_temporary_key_info(TLS_REC *tls, SSL *ssl)
|
|||
#endif /* SSL_get_server_tmp_key. */
|
||||
}
|
||||
|
||||
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server)
|
||||
GIOChannel *net_connect_ip_ssl_channel(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server)
|
||||
{
|
||||
GIOChannel *handle, *ssl_handle;
|
||||
GIOChannel *channel, *ssl_channel;
|
||||
|
||||
handle = net_connect_ip(ip, port, my_ip);
|
||||
if (handle == NULL)
|
||||
channel = net_connect_ip_channel(ip, port, my_ip);
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
ssl_handle = irssi_ssl_get_iochannel(handle, port, server);
|
||||
if (ssl_handle == NULL)
|
||||
g_io_channel_unref(handle);
|
||||
return ssl_handle;
|
||||
ssl_channel = irssi_ssl_get_iochannel(channel, port, server);
|
||||
if (ssl_channel == NULL)
|
||||
g_io_channel_unref(channel);
|
||||
return ssl_channel;
|
||||
}
|
||||
|
||||
GIOChannel *net_start_ssl(SERVER_REC *server)
|
||||
GIOChannel *net_start_ssl_channel(SERVER_REC *server)
|
||||
{
|
||||
GIOChannel *handle, *ssl_handle;
|
||||
GIOChannel *channel, *ssl_channel;
|
||||
|
||||
g_return_val_if_fail(server != NULL, NULL);
|
||||
|
||||
handle = net_sendbuffer_handle(server->handle);
|
||||
if (handle == NULL)
|
||||
channel = net_sendbuffer_channel(server->handle);
|
||||
if (channel == NULL)
|
||||
return NULL;
|
||||
|
||||
ssl_handle = irssi_ssl_get_iochannel(handle, server->connrec->port, server);
|
||||
return ssl_handle;
|
||||
ssl_channel = irssi_ssl_get_iochannel(channel, server->connrec->port, server);
|
||||
return ssl_channel;
|
||||
}
|
||||
|
||||
|
||||
int irssi_ssl_handshake(GIOChannel *handle)
|
||||
int irssi_ssl_handshake_channel(GIOChannel *channel)
|
||||
{
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||
GIOSSLChannel *chan = (GIOSSLChannel *) channel;
|
||||
int ret, err;
|
||||
const char *errstr = NULL;
|
||||
X509 *cert = NULL;
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip)
|
|||
}
|
||||
|
||||
/* Connect to socket with ip address */
|
||||
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
||||
GIOChannel *net_connect_ip_channel(IPADDR *ip, int port, IPADDR *my_ip)
|
||||
{
|
||||
int handle = -1;
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
|||
}
|
||||
|
||||
/* Connect to named UNIX socket */
|
||||
GIOChannel *net_connect_unix(const char *path)
|
||||
GIOChannel *net_connect_unix_channel(const char *path)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int handle, ret;
|
||||
|
|
@ -233,17 +233,25 @@ GIOChannel *net_connect_unix(const char *path)
|
|||
}
|
||||
|
||||
/* Disconnect socket */
|
||||
void net_disconnect(GIOChannel *handle)
|
||||
void net_disconnect_channel(GIOChannel *channel)
|
||||
{
|
||||
g_return_if_fail(handle != NULL);
|
||||
g_return_if_fail(channel != NULL);
|
||||
|
||||
g_io_channel_shutdown(handle, TRUE, NULL);
|
||||
g_io_channel_unref(handle);
|
||||
g_io_channel_shutdown(channel, TRUE, NULL);
|
||||
g_io_channel_unref(channel);
|
||||
}
|
||||
|
||||
void net_disconnect_stream(GIOStream *stream)
|
||||
{
|
||||
g_return_if_fail(stream != NULL);
|
||||
|
||||
g_io_stream_close(stream, NULL, NULL);
|
||||
g_object_unref(stream);
|
||||
}
|
||||
|
||||
/* Listen for connections on a socket. if `my_ip' is NULL, listen in any
|
||||
address. */
|
||||
GIOChannel *net_listen(IPADDR *my_ip, int *port)
|
||||
GIOChannel *net_listen_channel(IPADDR *my_ip, int *port)
|
||||
{
|
||||
union sockaddr_union so;
|
||||
int ret, handle, opt = 1;
|
||||
|
|
@ -296,16 +304,16 @@ GIOChannel *net_listen(IPADDR *my_ip, int *port)
|
|||
}
|
||||
|
||||
/* Accept a connection on a socket */
|
||||
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port)
|
||||
GIOChannel *net_accept_channel(GIOChannel *channel, IPADDR *addr, int *port)
|
||||
{
|
||||
union sockaddr_union so;
|
||||
int ret;
|
||||
socklen_t addrlen;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, NULL);
|
||||
g_return_val_if_fail(channel != NULL, NULL);
|
||||
|
||||
addrlen = sizeof(so);
|
||||
ret = accept(g_io_channel_unix_get_fd(handle), &so.sa, &addrlen);
|
||||
ret = accept(g_io_channel_unix_get_fd(channel), &so.sa, &addrlen);
|
||||
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
|
@ -318,16 +326,16 @@ GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port)
|
|||
}
|
||||
|
||||
/* Read data from socket, return number of bytes read, -1 = error */
|
||||
int net_receive(GIOChannel *handle, char *buf, int len)
|
||||
int net_receive_channel(GIOChannel *channel, char *buf, int len)
|
||||
{
|
||||
gsize ret;
|
||||
GIOStatus status;
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, -1);
|
||||
g_return_val_if_fail(channel != NULL, -1);
|
||||
g_return_val_if_fail(buf != NULL, -1);
|
||||
|
||||
status = g_io_channel_read_chars(handle, buf, len, &ret, &err);
|
||||
status = g_io_channel_read_chars(channel, buf, len, &ret, &err);
|
||||
if (err != NULL) {
|
||||
g_warning("%s", err->message);
|
||||
g_error_free(err);
|
||||
|
|
@ -338,17 +346,70 @@ int net_receive(GIOChannel *handle, char *buf, int len)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int net_receive_stream(GIOStream *stream, char *buf, int len)
|
||||
{
|
||||
GInputStream *iin;
|
||||
GPollableInputStream *in;
|
||||
GError *error;
|
||||
gsize ret;
|
||||
|
||||
g_return_val_if_fail(stream != NULL, -1);
|
||||
g_return_val_if_fail(buf != NULL, -1);
|
||||
|
||||
error = NULL;
|
||||
iin = g_io_stream_get_input_stream(stream);
|
||||
in = G_POLLABLE_INPUT_STREAM(iin);
|
||||
|
||||
ret = g_pollable_input_stream_read_nonblocking(in, buf, len, NULL, &error);
|
||||
if (error == NULL) {
|
||||
if (ret == 0) {
|
||||
g_warning("net_receive returned has_pending:%d, is_closed:%d, connection "
|
||||
"is_closed:%d, %lu [%s]",
|
||||
g_input_stream_has_pending(iin), g_input_stream_is_closed(iin),
|
||||
g_io_stream_is_closed(stream), ret, buf);
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
} else if (error->code == G_IO_ERROR_WOULD_BLOCK) {
|
||||
// g_warning("net_receive would block: %s, is_connected:%d", error->message,
|
||||
// g_socket_connection_is_connected((GSocketConnection *)stream));
|
||||
return 0;
|
||||
} else {
|
||||
g_warning("net_receive failed: %d:%s", error->code, error->message);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int net_transmit_stream(GIOStream *stream, const char *data, int len)
|
||||
{
|
||||
GPollableOutputStream *out;
|
||||
gsize ret;
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_val_if_fail(stream != NULL, -1);
|
||||
g_return_val_if_fail(data != NULL, -1);
|
||||
|
||||
out = G_POLLABLE_OUTPUT_STREAM(g_io_stream_get_output_stream(stream));
|
||||
ret = g_pollable_output_stream_write_nonblocking(out, data, len, NULL, &err);
|
||||
if (err == NULL || err->code == G_IO_ERROR_WOULD_BLOCK) {
|
||||
return ret;
|
||||
} else {
|
||||
g_warning("net_transmit: %d:%s", err->code, err->message);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Transmit data, return number of bytes sent, -1 = error */
|
||||
int net_transmit(GIOChannel *handle, const char *data, int len)
|
||||
int net_transmit_channel(GIOChannel *channel, const char *data, int len)
|
||||
{
|
||||
gsize ret;
|
||||
GIOStatus status;
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, -1);
|
||||
g_return_val_if_fail(channel != NULL, -1);
|
||||
g_return_val_if_fail(data != NULL, -1);
|
||||
|
||||
status = g_io_channel_write_chars(handle, (char *) data, len, &ret, &err);
|
||||
status = g_io_channel_write_chars(channel, (char *) data, len, &ret, &err);
|
||||
if (err != NULL) {
|
||||
g_warning("%s", err->message);
|
||||
g_error_free(err);
|
||||
|
|
@ -360,17 +421,16 @@ int net_transmit(GIOChannel *handle, const char *data, int len)
|
|||
}
|
||||
|
||||
/* Get socket address/port */
|
||||
int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port)
|
||||
int net_getsockname_channel(GIOChannel *channel, IPADDR *addr, int *port)
|
||||
{
|
||||
union sockaddr_union so;
|
||||
socklen_t addrlen;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, -1);
|
||||
g_return_val_if_fail(channel != NULL, -1);
|
||||
g_return_val_if_fail(addr != NULL, -1);
|
||||
|
||||
addrlen = sizeof(so);
|
||||
if (getsockname(g_io_channel_unix_get_fd(handle),
|
||||
(struct sockaddr *) &so, &addrlen) == -1)
|
||||
if (getsockname(g_io_channel_unix_get_fd(channel), (struct sockaddr *) &so, &addrlen) == -1)
|
||||
return -1;
|
||||
|
||||
sin_get_ip(&so, addr);
|
||||
|
|
@ -518,13 +578,13 @@ int net_host2ip(const char *host, IPADDR *ip)
|
|||
}
|
||||
|
||||
/* Get socket error */
|
||||
int net_geterror(GIOChannel *handle)
|
||||
int net_geterror_channel(GIOChannel *channel)
|
||||
{
|
||||
int data;
|
||||
socklen_t len = sizeof(data);
|
||||
|
||||
if (getsockopt(g_io_channel_unix_get_fd(handle),
|
||||
SOL_SOCKET, SO_ERROR, (void *) &data, &len) == -1)
|
||||
if (getsockopt(g_io_channel_unix_get_fd(channel), SOL_SOCKET, SO_ERROR, (void *) &data,
|
||||
&len) == -1)
|
||||
return -1;
|
||||
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -57,34 +57,40 @@ int i_io_channel_read_block(GIOChannel *channel, void *data, int len);
|
|||
int net_connect_ip_handle(const IPADDR *ip, int port, const IPADDR *my_ip);
|
||||
|
||||
/* Connect to socket with ip address and SSL*/
|
||||
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server);
|
||||
GIOChannel *net_connect_ip_ssl_channel(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server);
|
||||
/* Start TLS */
|
||||
GIOChannel *net_start_ssl(SERVER_REC *server);
|
||||
GIOChannel *net_start_ssl_channel(SERVER_REC *server);
|
||||
|
||||
int irssi_ssl_handshake(GIOChannel *handle);
|
||||
int irssi_ssl_handshake_channel(GIOChannel *channel);
|
||||
/* Connect to socket with ip address */
|
||||
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
|
||||
GIOChannel *net_connect_ip_channel(IPADDR *ip, int port, IPADDR *my_ip);
|
||||
/* Connect to named UNIX socket */
|
||||
GIOChannel *net_connect_unix(const char *path);
|
||||
GIOChannel *net_connect_unix_channel(const char *path);
|
||||
/* Disconnect socket */
|
||||
void net_disconnect(GIOChannel *handle);
|
||||
void net_disconnect_channel(GIOChannel *channel);
|
||||
/* Disconnect socket */
|
||||
void net_disconnect_stream(GIOStream *stream);
|
||||
|
||||
/* Listen for connections on a socket */
|
||||
GIOChannel *net_listen(IPADDR *my_ip, int *port);
|
||||
GIOChannel *net_listen_channel(IPADDR *my_ip, int *port);
|
||||
/* Accept a connection on a socket */
|
||||
GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port);
|
||||
GIOChannel *net_accept_channel(GIOChannel *channel, IPADDR *addr, int *port);
|
||||
|
||||
/* Read data from socket, return number of bytes read, -1 = error */
|
||||
int net_receive(GIOChannel *handle, char *buf, int len);
|
||||
int net_receive_channel(GIOChannel *channel, char *buf, int len);
|
||||
/* Read data from stream, return number of bytes read, -1 = error */
|
||||
int net_receive_stream(GIOStream *stream, char *buf, int len);
|
||||
/* Transmit data, return number of bytes sent, -1 = error */
|
||||
int net_transmit(GIOChannel *handle, const char *data, int len);
|
||||
int net_transmit_channel(GIOChannel *channel, const char *data, int len);
|
||||
/* Transmit data, return number of bytes sent, -1 = error */
|
||||
int net_transmit_stream(GIOStream *stream, const char *data, int len);
|
||||
|
||||
/* 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);
|
||||
int net_getsockname_channel(GIOChannel *channel, IPADDR *addr, int *port);
|
||||
|
||||
/* IPADDR -> char* translation. `host' must be at least MAX_IP_LEN bytes */
|
||||
int net_ip2host(IPADDR *ip, char *host);
|
||||
|
|
@ -92,7 +98,7 @@ int net_ip2host(IPADDR *ip, char *host);
|
|||
int net_host2ip(const char *host, IPADDR *ip);
|
||||
|
||||
/* Get socket error */
|
||||
int net_geterror(GIOChannel *handle);
|
||||
int net_geterror_channel(GIOChannel *channel);
|
||||
|
||||
/* Get name of TCP service */
|
||||
char *net_getservbyport(int port);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ int refcount;
|
|||
char *proxy;
|
||||
int proxy_port;
|
||||
char *proxy_string, *proxy_string_after, *proxy_password;
|
||||
GProxyResolver *proxy_resolver;
|
||||
|
||||
unsigned short family; /* 0 = don't care, AF_INET or AF_INET6 */
|
||||
unsigned short chosen_family; /* family actually chosen during name resolution */
|
||||
|
|
@ -33,8 +34,9 @@ char *tls_capath;
|
|||
char *tls_ciphers;
|
||||
char *tls_pinned_cert;
|
||||
char *tls_pinned_pubkey;
|
||||
GSocketConnectable *tls_identity;
|
||||
|
||||
GIOChannel *connect_handle; /* connect using this handle */
|
||||
GIOChannel *connect_channel; /* connect using this handle */
|
||||
|
||||
/* when reconnecting, the old server status */
|
||||
unsigned int reconnection:1; /* we're trying to reconnect a connected server */
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ void server_connect_finished(SERVER_REC *server)
|
|||
signal_emit("server connected", 1, server);
|
||||
}
|
||||
|
||||
static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
|
||||
static void server_connect_callback_init_channel(SERVER_REC *server, GIOChannel *channel)
|
||||
{
|
||||
int error;
|
||||
|
||||
g_return_if_fail(IS_SERVER(server));
|
||||
|
||||
error = net_geterror(handle);
|
||||
error = net_geterror_channel(channel);
|
||||
if (error != 0) {
|
||||
server->connection_lost = TRUE;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
|
|
@ -164,13 +164,34 @@ static void server_connect_callback_init(SERVER_REC *server, GIOChannel *handle)
|
|||
server_connect_finished(server);
|
||||
}
|
||||
|
||||
static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *handle)
|
||||
static gboolean server_connect_callback_init_source(GSocket *socket, GIOCondition cond,
|
||||
SERVER_REC *server)
|
||||
{
|
||||
g_return_val_if_fail(IS_SERVER(server), FALSE);
|
||||
|
||||
if (cond & (G_IO_ERR | G_IO_HUP)) {
|
||||
server->connection_lost = TRUE;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
server_connect_failed(server, "Connection broken"); // TODO: g_strerror(error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lookup_servers = g_slist_remove(lookup_servers, server);
|
||||
g_source_remove(server->connect_tag);
|
||||
server->connect_tag = -1;
|
||||
|
||||
server_connect_finished(server);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void server_connect_callback_init_ssl_channel(SERVER_REC *server, GIOChannel *channel)
|
||||
{
|
||||
int error;
|
||||
|
||||
g_return_if_fail(IS_SERVER(server));
|
||||
|
||||
error = irssi_ssl_handshake(handle);
|
||||
error = irssi_ssl_handshake_channel(channel);
|
||||
if (error == -1) {
|
||||
server->connection_lost = TRUE;
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
|
|
@ -181,8 +202,8 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han
|
|||
if (server->connect_tag != -1)
|
||||
g_source_remove(server->connect_tag);
|
||||
server->connect_tag =
|
||||
i_input_add(handle, error == 1 ? I_INPUT_READ : I_INPUT_WRITE,
|
||||
(GInputFunction) server_connect_callback_init_ssl, server);
|
||||
i_input_add(channel, error == 1 ? I_INPUT_READ : I_INPUT_WRITE,
|
||||
(GInputFunction) server_connect_callback_init_ssl_channel, server);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -195,17 +216,100 @@ static void server_connect_callback_init_ssl(SERVER_REC *server, GIOChannel *han
|
|||
server_connect_finished(server);
|
||||
}
|
||||
|
||||
static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
||||
const char *unix_socket)
|
||||
void server_real_connect_connected(GSocketClient *client, GAsyncResult *res, SERVER_REC *server)
|
||||
{
|
||||
GIOChannel *handle;
|
||||
IPADDR *own_ip = NULL;
|
||||
GIOStream *stream;
|
||||
// int fd;
|
||||
// GIOChannel *channel;
|
||||
GError *error;
|
||||
error = NULL;
|
||||
stream = (GIOStream *) g_socket_client_connect_finish(client, res, &error);
|
||||
g_object_unref(client);
|
||||
if (error != NULL) {
|
||||
const char *errormsg = error->message;
|
||||
if (errormsg == NULL)
|
||||
errormsg = "Connect failed";
|
||||
if (error->code == G_IO_ERROR_CONNECTION_REFUSED) {
|
||||
#if 0
|
||||
// TODO
|
||||
if (own_ip != NULL) {
|
||||
/* show the IP which is causing the error */
|
||||
net_ip2host(own_ip, ipaddr);
|
||||
errmsg2 = g_strconcat(errmsg, ": ", ipaddr, NULL);
|
||||
}
|
||||
#endif
|
||||
server->no_reconnect = TRUE;
|
||||
}
|
||||
#if 0
|
||||
// TODO
|
||||
if (server->connrec->use_tls && errno == ENOSYS)
|
||||
server->no_reconnect = TRUE;
|
||||
#endif
|
||||
|
||||
server->connection_lost = TRUE;
|
||||
if (server->connrec->ipaddr != NULL) {
|
||||
server->connrec->last_failed = server->connrec->last_connected;
|
||||
}
|
||||
server_connect_failed(server, errormsg);
|
||||
} else {
|
||||
GSocket *socket;
|
||||
GSource *source;
|
||||
|
||||
server->connrec->last_failed = 0;
|
||||
g_object_ref(stream); // TODO: unref
|
||||
g_assert(server->handle == NULL);
|
||||
server->handle = net_sendbuffer_create_stream(stream, 0);
|
||||
socket = g_socket_connection_get_socket((GSocketConnection *) stream);
|
||||
source = g_socket_create_source(socket, G_IO_IN | G_IO_OUT, NULL);
|
||||
g_source_set_callback(source, G_SOURCE_FUNC(server_connect_callback_init_source),
|
||||
server, NULL);
|
||||
server->connect_tag = g_source_attach(source, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void server_real_connect_event(GSocketClient *client, GSocketClientEvent event,
|
||||
GSocketConnectable *connectable, GIOStream *stream,
|
||||
SERVER_REC *server)
|
||||
{
|
||||
if (event == G_SOCKET_CLIENT_TLS_HANDSHAKING) {
|
||||
server->connrec->tls_identity =
|
||||
g_network_address_new(server->connrec->address, server->connrec->port);
|
||||
g_tls_client_connection_set_server_identity((GTlsClientConnection *) stream,
|
||||
server->connrec->tls_identity);
|
||||
if (server->connrec->tls_cert != NULL) {
|
||||
GTlsCertificate *cert;
|
||||
GError *err;
|
||||
char *scert;
|
||||
scert = convert_home(server->connrec->tls_cert);
|
||||
err = NULL;
|
||||
cert = g_tls_certificate_new_from_file(scert, &err);
|
||||
if (err != NULL) {
|
||||
g_warning("Tls Certificate: %s", err->message);
|
||||
} else {
|
||||
g_tls_connection_set_certificate((GTlsConnection *) stream, cert);
|
||||
}
|
||||
if (cert != NULL) {
|
||||
g_object_unref(cert);
|
||||
}
|
||||
g_free(scert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void server_real_connect(SERVER_REC *server, IPADDR *ip, const char *unix_socket,
|
||||
const char *host)
|
||||
{
|
||||
/*
|
||||
GIOChannel *channel;
|
||||
const char *errmsg;
|
||||
char *errmsg2;
|
||||
IPADDR *own_ip = NULL;
|
||||
*/
|
||||
GSocketClient *client;
|
||||
char ipaddr[MAX_IP_LEN];
|
||||
int port = 0;
|
||||
|
||||
g_return_if_fail(ip != NULL || unix_socket != NULL);
|
||||
g_return_if_fail(ip != NULL || unix_socket != NULL || host != NULL);
|
||||
|
||||
if (ip != NULL) {
|
||||
server->connrec->chosen_family = ip->family;
|
||||
|
|
@ -213,32 +317,69 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||
server->connrec->ipaddr = g_strdup(ipaddr);
|
||||
}
|
||||
|
||||
signal_emit("server connecting", 2, server, ip);
|
||||
signal_emit("server connecting", 3, server, ip, ip != NULL ? ipaddr : host);
|
||||
|
||||
if (server->connrec->no_connect)
|
||||
return;
|
||||
|
||||
/*
|
||||
if (ip != NULL) {
|
||||
own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
|
||||
port = server->connrec->proxy != NULL ?
|
||||
server->connrec->proxy_port : server->connrec->port;
|
||||
handle = net_connect_ip(ip, port, own_ip);
|
||||
channel = net_connect_ip_channel(ip, port, own_ip);
|
||||
} else {
|
||||
handle = net_connect_unix(unix_socket);
|
||||
channel = net_connect_unix_channel(unix_socket);
|
||||
*/
|
||||
|
||||
client = g_socket_client_new();
|
||||
// server->connect_cancellable = g_cancellable_new();
|
||||
if (ip != NULL || host != NULL) {
|
||||
// own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
|
||||
port = /* server->connrec->proxy != NULL ?
|
||||
server->connrec->proxy_port : */
|
||||
server->connrec->port;
|
||||
if (server->connrec->use_tls)
|
||||
g_socket_client_set_tls(client, TRUE);
|
||||
if (server->connrec->proxy != NULL) {
|
||||
GProxyResolver *res;
|
||||
char *addr;
|
||||
addr = g_strdup_printf("socks://%s:%d", server->connrec->proxy,
|
||||
server->connrec->proxy_port);
|
||||
res = g_simple_proxy_resolver_new(addr, NULL);
|
||||
// g_free(addr); // TODO: free
|
||||
g_warning("configuring %s as proxy", addr);
|
||||
g_socket_client_set_proxy_resolver(client, res);
|
||||
g_socket_client_set_enable_proxy(client, TRUE);
|
||||
server->connrec->proxy_resolver = res;
|
||||
}
|
||||
g_signal_connect(client, "event", G_CALLBACK(server_real_connect_event), server);
|
||||
g_socket_client_connect_to_host_async(
|
||||
client, ip ? ipaddr : host, port, server->connect_cancellable,
|
||||
(GAsyncReadyCallback) server_real_connect_connected, server);
|
||||
return;
|
||||
} else {
|
||||
GSocketAddress *addr;
|
||||
addr = g_unix_socket_address_new(unix_socket);
|
||||
g_socket_client_connect_async(
|
||||
client, (GSocketConnectable *) addr, server->connect_cancellable,
|
||||
(GAsyncReadyCallback) server_real_connect_connected, server);
|
||||
return;
|
||||
}
|
||||
|
||||
if (server->connrec->use_tls && handle != NULL) {
|
||||
server->handle = net_sendbuffer_create(handle, 0);
|
||||
handle = net_start_ssl(server);
|
||||
if (handle == NULL) {
|
||||
#if 0
|
||||
if (server->connrec->use_tls && channel != NULL) {
|
||||
server->handle = net_sendbuffer_create_channel(channel, 0);
|
||||
channel = net_start_ssl_channel(server);
|
||||
if (channel == NULL) {
|
||||
net_sendbuffer_destroy(server->handle, TRUE);
|
||||
server->handle = NULL;
|
||||
} else {
|
||||
server->handle->handle = handle;
|
||||
server->handle->channel = channel;
|
||||
}
|
||||
}
|
||||
|
||||
if (handle == NULL) {
|
||||
if (channel == NULL) {
|
||||
/* failed */
|
||||
errmsg = g_strerror(errno);
|
||||
errmsg2 = NULL;
|
||||
|
|
@ -262,14 +403,15 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||
} else {
|
||||
server->connrec->last_failed = 0;
|
||||
if (!server->connrec->use_tls)
|
||||
server->handle = net_sendbuffer_create(handle, 0);
|
||||
server->handle = net_sendbuffer_create_channel(channel, 0);
|
||||
if (server->connrec->use_tls)
|
||||
server_connect_callback_init_ssl(server, handle);
|
||||
server_connect_callback_init_ssl_channel(server, channel);
|
||||
else
|
||||
server->connect_tag =
|
||||
i_input_add(handle, I_INPUT_WRITE | I_INPUT_READ,
|
||||
(GInputFunction) server_connect_callback_init, server);
|
||||
server->connect_tag = i_input_add(
|
||||
channel, I_INPUT_WRITE | I_INPUT_READ,
|
||||
(GInputFunction) server_connect_callback_init_channel, server);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int server_start_connect_resolve(SERVER_REC *server);
|
||||
|
|
@ -280,6 +422,11 @@ static void server_connect_use_resolved(SERVER_REC *server)
|
|||
const char *errormsg;
|
||||
RESOLVED_IP_REC *iprec = server->connrec->resolved_host;
|
||||
|
||||
if (server->connrec->proxy != NULL) {
|
||||
server_real_connect(server, NULL, NULL, server->connrec->address);
|
||||
errormsg = NULL;
|
||||
return;
|
||||
}
|
||||
if (iprec->error != NULL) {
|
||||
/* error */
|
||||
ip = NULL;
|
||||
|
|
@ -318,7 +465,7 @@ static void server_connect_use_resolved(SERVER_REC *server)
|
|||
|
||||
if (ip != NULL) {
|
||||
/* host lookup ok */
|
||||
server_real_connect(server, ip, NULL);
|
||||
server_real_connect(server, ip, NULL, NULL);
|
||||
errormsg = NULL;
|
||||
} else {
|
||||
if (iprec->error->code == G_RESOLVER_ERROR_NOT_FOUND) {
|
||||
|
|
@ -368,8 +515,12 @@ static int server_start_connect_resolve(SERVER_REC *server)
|
|||
const char *connect_address;
|
||||
GResolverNameLookupFlags net_gethostbyname_flags;
|
||||
|
||||
if (server->connrec->proxy != NULL)
|
||||
return TRUE;
|
||||
|
||||
connect_address =
|
||||
server->connrec->proxy != NULL ? server->connrec->proxy : server->connrec->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;
|
||||
|
|
@ -441,16 +592,17 @@ int server_start_connect(SERVER_REC *server)
|
|||
|
||||
server->rawlog = rawlog_create();
|
||||
|
||||
if (server->connrec->connect_handle != NULL) {
|
||||
// TODO connect_connection
|
||||
if (server->connrec->connect_channel != NULL) {
|
||||
/* already connected */
|
||||
GIOChannel *handle = server->connrec->connect_handle;
|
||||
GIOChannel *channel = server->connrec->connect_channel;
|
||||
|
||||
server->connrec->connect_handle = NULL;
|
||||
server->handle = net_sendbuffer_create(handle, 0);
|
||||
server->connrec->connect_channel = NULL;
|
||||
server->handle = net_sendbuffer_create_channel(channel, 0);
|
||||
server_connect_finished(server);
|
||||
} else if (server->connrec->unix_socket) {
|
||||
/* connect with unix socket */
|
||||
server_real_connect(server, NULL, server->connrec->address);
|
||||
server_real_connect(server, NULL, server->connrec->address, NULL);
|
||||
} else {
|
||||
int already_resolved;
|
||||
/* resolve host name */
|
||||
|
|
@ -564,7 +716,7 @@ int server_unref(SERVER_REC *server)
|
|||
/* we were on some channels, try to let the server
|
||||
disconnect so that our quit message is guaranteed
|
||||
to get displayed */
|
||||
net_disconnect_later(net_sendbuffer_handle(server->handle));
|
||||
net_disconnect_later(server->handle);
|
||||
net_sendbuffer_destroy(server->handle, FALSE);
|
||||
}
|
||||
server->handle = NULL;
|
||||
|
|
@ -654,14 +806,18 @@ void server_connect_unref(SERVER_CONNECT_REC *conn)
|
|||
|
||||
CHAT_PROTOCOL(conn)->destroy_server_connect(conn);
|
||||
|
||||
if (conn->connect_handle != NULL)
|
||||
net_disconnect(conn->connect_handle);
|
||||
if (conn->connect_channel != NULL)
|
||||
net_disconnect_channel(conn->connect_channel);
|
||||
|
||||
g_free_not_null(conn->proxy);
|
||||
g_free_not_null(conn->proxy_string);
|
||||
g_free_not_null(conn->proxy_string_after);
|
||||
g_free_not_null(conn->proxy_password);
|
||||
if (conn->proxy_resolver != NULL)
|
||||
g_object_unref(conn->proxy_resolver);
|
||||
|
||||
if (conn->tls_identity != NULL)
|
||||
g_object_unref(conn->tls_identity);
|
||||
g_free_not_null(conn->ipaddr);
|
||||
g_free_not_null(conn->tag);
|
||||
g_free_not_null(conn->address);
|
||||
|
|
|
|||
|
|
@ -175,13 +175,13 @@ static void session_save_server(SERVER_REC *server, CONFIG_REC *config,
|
|||
config_node_set_str(config, node, "tls_pinned_cert", server->connrec->tls_pinned_cert);
|
||||
config_node_set_str(config, node, "tls_pinned_pubkey", server->connrec->tls_pinned_pubkey);
|
||||
|
||||
handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
|
||||
handle = g_io_channel_unix_get_fd(net_sendbuffer_channel(server->handle));
|
||||
config_node_set_int(config, node, "handle", handle);
|
||||
|
||||
signal_emit("session save server", 3, server, config, node);
|
||||
|
||||
/* fake the server disconnection */
|
||||
g_io_channel_unref(net_sendbuffer_handle(server->handle));
|
||||
g_io_channel_unref(net_sendbuffer_channel(server->handle));
|
||||
net_sendbuffer_destroy(server->handle, FALSE);
|
||||
server->handle = NULL;
|
||||
|
||||
|
|
@ -282,7 +282,7 @@ static void session_restore_server(CONFIG_NODE *node)
|
|||
conn->tls_pinned_pubkey = g_strdup(config_node_get_str(node, "tls_pinned_pubkey", NULL));
|
||||
|
||||
conn->reconnection = TRUE;
|
||||
conn->connect_handle = i_io_channel_new(handle);
|
||||
conn->connect_channel = i_io_channel_new(handle);
|
||||
|
||||
server = proto->server_init_connect(conn);
|
||||
server->version = g_strdup(config_node_get_str(node, "version", NULL));
|
||||
|
|
|
|||
|
|
@ -305,9 +305,9 @@ static void process_exec(PROCESS_REC *rec, const char *cmd)
|
|||
GIOChannel *outio = i_io_channel_new(in[1]);
|
||||
|
||||
rec->in = i_io_channel_new(out[0]);
|
||||
rec->out = net_sendbuffer_create(outio, 0);
|
||||
rec->out = net_sendbuffer_create_channel(outio, 0);
|
||||
|
||||
close(out[1]);
|
||||
close(out[1]);
|
||||
close(in[0]);
|
||||
pidwait_add(rec->pid);
|
||||
return;
|
||||
|
|
@ -360,7 +360,7 @@ static void sig_exec_input_reader(PROCESS_REC *rec)
|
|||
|
||||
g_return_if_fail(rec != NULL);
|
||||
|
||||
recvlen = net_receive(rec->in, tmpbuf, sizeof(tmpbuf));
|
||||
recvlen = net_receive_channel(rec->in, tmpbuf, sizeof(tmpbuf));
|
||||
do {
|
||||
ret = line_split(tmpbuf, recvlen, &str, &rec->databuf);
|
||||
if (ret == -1) {
|
||||
|
|
|
|||
|
|
@ -323,7 +323,7 @@ static void server_init_1(IRC_SERVER_REC *server)
|
|||
server_init_2(server);
|
||||
}
|
||||
|
||||
static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle)
|
||||
static void init_ssl_loop_channel(IRC_SERVER_REC *server, GIOChannel *channel)
|
||||
{
|
||||
int error;
|
||||
server->connrec->starttls = 1;
|
||||
|
|
@ -333,7 +333,7 @@ static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle)
|
|||
server->starttls_tag = 0;
|
||||
}
|
||||
|
||||
error = irssi_ssl_handshake(handle);
|
||||
error = irssi_ssl_handshake_channel(channel);
|
||||
if (error == -1) {
|
||||
server->connection_lost = TRUE;
|
||||
server_disconnect((SERVER_REC *) server);
|
||||
|
|
@ -341,8 +341,8 @@ static void init_ssl_loop(IRC_SERVER_REC *server, GIOChannel *handle)
|
|||
}
|
||||
if (error & 1) { /* wait */
|
||||
server->starttls_tag =
|
||||
i_input_add(handle, error == 1 ? I_INPUT_READ : I_INPUT_WRITE,
|
||||
(GInputFunction) init_ssl_loop, server);
|
||||
i_input_add(channel, error == 1 ? I_INPUT_READ : I_INPUT_WRITE,
|
||||
(GInputFunction) init_ssl_loop_channel, server);
|
||||
return;
|
||||
}
|
||||
/* continue */
|
||||
|
|
@ -375,7 +375,7 @@ void irc_server_send_starttls(IRC_SERVER_REC *server)
|
|||
|
||||
static void event_starttls(IRC_SERVER_REC *server, const char *data)
|
||||
{
|
||||
GIOChannel *ssl_handle;
|
||||
GIOChannel *ssl_channel;
|
||||
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
|
|
@ -387,15 +387,20 @@ static void event_starttls(IRC_SERVER_REC *server, const char *data)
|
|||
char *str;
|
||||
line_split("", -1, &str, &server->handle->readbuffer);
|
||||
}
|
||||
ssl_handle = net_start_ssl((SERVER_REC *) server);
|
||||
if (ssl_handle != NULL) {
|
||||
#if 0
|
||||
// TODO
|
||||
ssl_channel = net_start_ssl_channel((SERVER_REC *) server);
|
||||
if (ssl_channel != NULL) {
|
||||
g_source_remove(server->readtag);
|
||||
server->readtag = -1;
|
||||
server->handle->handle = ssl_handle;
|
||||
init_ssl_loop(server, server->handle->handle);
|
||||
server->handle->channel = ssl_channel;
|
||||
init_ssl_loop_channel(server, server->handle->channel);
|
||||
} else {
|
||||
g_warning("net_start_ssl failed");
|
||||
#endif
|
||||
g_warning("net_start_ssl failed");
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void event_registerfirst(IRC_SERVER_REC *server, const char *data)
|
||||
|
|
@ -485,7 +490,7 @@ void irc_server_connect(SERVER_REC *server)
|
|||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
||||
if (server->connrec->connect_handle != NULL) {
|
||||
if (server->connrec->connect_channel != NULL) {
|
||||
/* an existing handle from upgrade */
|
||||
IRC_SERVER_CONNECT_REC *conn;
|
||||
int tls_disconnect;
|
||||
|
|
@ -495,8 +500,8 @@ void irc_server_connect(SERVER_REC *server)
|
|||
|
||||
if (tls_disconnect) {
|
||||
/* we cannot use it, it is encrypted. force a reconnect */
|
||||
g_io_channel_unref(conn->connect_handle);
|
||||
conn->connect_handle = NULL;
|
||||
g_io_channel_unref(conn->connect_channel);
|
||||
conn->connect_channel = NULL;
|
||||
server->session_reconnect = FALSE;
|
||||
server_connect_ref((SERVER_CONNECT_REC *) conn);
|
||||
server_disconnect(server);
|
||||
|
|
@ -695,23 +700,24 @@ void irc_server_send_away(IRC_SERVER_REC *server, const char *reason)
|
|||
|
||||
void irc_server_send_data(IRC_SERVER_REC *server, const char *data, int len)
|
||||
{
|
||||
if (net_sendbuffer_send(server->handle, data, len) == -1) {
|
||||
/* something bad happened */
|
||||
server->connection_lost = TRUE;
|
||||
return;
|
||||
}
|
||||
if (server->handle != NULL) {
|
||||
if (net_sendbuffer_send(server->handle, data, len) == -1) {
|
||||
/* something bad happened */
|
||||
server->connection_lost = TRUE;
|
||||
return;
|
||||
}
|
||||
server->last_cmd = g_get_real_time();
|
||||
|
||||
server->last_cmd = g_get_real_time();
|
||||
|
||||
/* A bit kludgy way to do the flood protection. In ircnet, there
|
||||
actually is 1sec / 100 bytes penalty, but we rather want to deal
|
||||
with the max. 1000 bytes input buffer problem. If we send more
|
||||
than that with the burst, we'll get excess flooded. */
|
||||
if (len < 100 || server->cmd_queue_speed <= 10)
|
||||
server->wait_cmd = 0;
|
||||
else {
|
||||
server->wait_cmd = server->last_cmd;
|
||||
server->wait_cmd += (2 + len / 100) * G_USEC_PER_SEC;
|
||||
/* A bit kludgy way to do the flood protection. In ircnet, there
|
||||
actually is 1sec / 100 bytes penalty, but we rather want to deal
|
||||
with the max. 1000 bytes input buffer problem. If we send more
|
||||
than that with the burst, we'll get excess flooded. */
|
||||
if (len < 100 || server->cmd_queue_speed <= 10)
|
||||
server->wait_cmd = 0;
|
||||
else {
|
||||
server->wait_cmd = server->last_cmd;
|
||||
server->wait_cmd += (2 + len / 100) * G_USEC_PER_SEC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -572,6 +572,16 @@ static void irc_parse_incoming(SERVER_REC *server)
|
|||
server_unref(server);
|
||||
}
|
||||
|
||||
static gboolean irc_parse_incoming_source(GObject *pollable_stream, SERVER_REC *server)
|
||||
{
|
||||
g_return_val_if_fail(server != NULL, FALSE);
|
||||
// g_warning("irc_parse_incoming_source");
|
||||
|
||||
irc_parse_incoming(server);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void irc_init_server(IRC_SERVER_REC *server)
|
||||
{
|
||||
g_return_if_fail(server != NULL);
|
||||
|
|
@ -579,8 +589,20 @@ static void irc_init_server(IRC_SERVER_REC *server)
|
|||
if (!IS_IRC_SERVER(server))
|
||||
return;
|
||||
|
||||
server->readtag = i_input_add(net_sendbuffer_handle(server->handle), I_INPUT_READ,
|
||||
(GInputFunction) irc_parse_incoming, server);
|
||||
if (server->handle->channel != NULL) {
|
||||
server->readtag = i_input_add(net_sendbuffer_channel(server->handle), I_INPUT_READ,
|
||||
(GInputFunction) irc_parse_incoming, server);
|
||||
} else {
|
||||
GInputStream *in;
|
||||
GSource *source;
|
||||
|
||||
in = g_io_stream_get_input_stream(server->handle->stream);
|
||||
source = g_pollable_input_stream_create_source(G_POLLABLE_INPUT_STREAM(in), NULL);
|
||||
g_source_set_callback(source, G_SOURCE_FUNC(irc_parse_incoming_source), server,
|
||||
NULL);
|
||||
server->readtag = g_source_attach(source, NULL);
|
||||
g_warning("readtag: %d", server->readtag);
|
||||
}
|
||||
}
|
||||
|
||||
void irc_irc_init(void)
|
||||
|
|
|
|||
|
|
@ -337,29 +337,29 @@ void dcc_chat_input(CHAT_DCC_REC *dcc)
|
|||
static void dcc_chat_listen(CHAT_DCC_REC *dcc)
|
||||
{
|
||||
IPADDR ip;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
int port;
|
||||
|
||||
g_return_if_fail(IS_DCC_CHAT(dcc));
|
||||
|
||||
/* accept connection */
|
||||
handle = net_accept(dcc->handle, &ip, &port);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_channel(dcc->channel, &ip, &port);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
|
||||
/* TODO: add paranoia check - see dcc-files.c */
|
||||
|
||||
net_disconnect(dcc->handle);
|
||||
net_disconnect_channel(dcc->channel);
|
||||
g_source_remove(dcc->tagconn);
|
||||
dcc->tagconn = -1;
|
||||
|
||||
dcc->starttime = time(NULL);
|
||||
dcc->handle = handle;
|
||||
dcc->sendbuf = net_sendbuffer_create(handle, 0);
|
||||
dcc->channel = channel;
|
||||
dcc->sendbuf = net_sendbuffer_create_channel(channel, 0);
|
||||
memcpy(&dcc->addr, &ip, sizeof(IPADDR));
|
||||
net_ip2host(&dcc->addr, dcc->addrstr);
|
||||
dcc->port = port;
|
||||
dcc->tagread = i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc);
|
||||
dcc->tagread = i_input_add(channel, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc);
|
||||
|
||||
signal_emit("dcc connected", 1, dcc);
|
||||
}
|
||||
|
|
@ -369,7 +369,7 @@ static void sig_chat_connected(CHAT_DCC_REC *dcc)
|
|||
{
|
||||
g_return_if_fail(IS_DCC_CHAT(dcc));
|
||||
|
||||
if (net_geterror(dcc->handle) != 0) {
|
||||
if (net_geterror_channel(dcc->channel) != 0) {
|
||||
/* error connecting */
|
||||
signal_emit("dcc error connect", 1, dcc);
|
||||
dcc_destroy(DCC(dcc));
|
||||
|
|
@ -381,8 +381,9 @@ static void sig_chat_connected(CHAT_DCC_REC *dcc)
|
|||
dcc->tagconn = -1;
|
||||
|
||||
dcc->starttime = time(NULL);
|
||||
dcc->sendbuf = net_sendbuffer_create(dcc->handle, 0);
|
||||
dcc->tagread = i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc);
|
||||
dcc->sendbuf = net_sendbuffer_create_channel(dcc->channel, 0);
|
||||
dcc->tagread =
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) dcc_chat_input, dcc);
|
||||
|
||||
signal_emit("dcc connected", 1, dcc);
|
||||
}
|
||||
|
|
@ -391,15 +392,14 @@ static void dcc_chat_connect(CHAT_DCC_REC *dcc)
|
|||
{
|
||||
g_return_if_fail(IS_DCC_CHAT(dcc));
|
||||
|
||||
if (dcc->addrstr[0] == '\0' ||
|
||||
dcc->starttime != 0 || dcc->handle != NULL) {
|
||||
if (dcc->addrstr[0] == '\0' || dcc->starttime != 0 || dcc->channel != NULL) {
|
||||
/* already sent a chat request / already chatting */
|
||||
return;
|
||||
}
|
||||
|
||||
dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port);
|
||||
if (dcc->handle != NULL) {
|
||||
dcc->tagconn = i_input_add(dcc->handle, I_INPUT_WRITE | I_INPUT_READ,
|
||||
dcc->channel = dcc_connect_ip_channel(&dcc->addr, dcc->port);
|
||||
if (dcc->channel != NULL) {
|
||||
dcc->tagconn = i_input_add(dcc->channel, I_INPUT_WRITE | I_INPUT_READ,
|
||||
(GInputFunction) sig_chat_connected, dcc);
|
||||
} else {
|
||||
/* error connecting */
|
||||
|
|
@ -412,25 +412,23 @@ static void dcc_chat_passive(CHAT_DCC_REC *dcc)
|
|||
{
|
||||
IPADDR own_ip;
|
||||
int port;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
char host[MAX_IP_LEN];
|
||||
|
||||
g_return_if_fail(IS_DCC_CHAT(dcc));
|
||||
|
||||
if (dcc->addrstr[0] == '\0' ||
|
||||
dcc->starttime != 0 || dcc->handle != NULL) {
|
||||
if (dcc->addrstr[0] == '\0' || dcc->starttime != 0 || dcc->channel != NULL) {
|
||||
/* already sent a chat request / already chatting */
|
||||
return;
|
||||
}
|
||||
|
||||
handle = dcc_listen(net_sendbuffer_handle(dcc->server->handle),
|
||||
&own_ip, &port);
|
||||
if (handle == NULL)
|
||||
channel = dcc_listen_channel(net_sendbuffer_channel(dcc->server->handle), &own_ip, &port);
|
||||
if (channel == NULL)
|
||||
cmd_return_error(CMDERR_ERRNO);
|
||||
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
dcc->tagconn =
|
||||
i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc);
|
||||
|
||||
/* Let's send the reply to the other client! */
|
||||
dcc_ip2str(&own_ip, host);
|
||||
|
|
@ -445,7 +443,7 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
|
|||
void *free_arg;
|
||||
CHAT_DCC_REC *dcc;
|
||||
IPADDR own_ip;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
GHashTable *optlist;
|
||||
int p_id;
|
||||
char *nick, host[MAX_IP_LEN];
|
||||
|
|
@ -470,7 +468,7 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
|
|||
}
|
||||
|
||||
dcc = dcc_chat_find_id(nick);
|
||||
if (dcc != NULL && dcc_is_waiting_user(dcc)) {
|
||||
if (dcc != NULL && dcc_is_waiting_user_channel(dcc)) {
|
||||
if (!dcc_is_passive(dcc)) {
|
||||
/* found from dcc chat requests,
|
||||
we're the connecting side */
|
||||
|
|
@ -483,8 +481,7 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
|
|||
return;
|
||||
}
|
||||
|
||||
if (dcc != NULL && dcc_is_listening(dcc) &&
|
||||
dcc->server == server) {
|
||||
if (dcc != NULL && dcc_is_listening_channel(dcc) && dcc->server == server) {
|
||||
/* sending request again even while old request is
|
||||
still waiting, remove it. */
|
||||
dcc_destroy(DCC(dcc));
|
||||
|
|
@ -502,14 +499,14 @@ static void cmd_dcc_chat(const char *data, IRC_SERVER_REC *server)
|
|||
|
||||
if (g_hash_table_lookup(optlist, "passive") == NULL) {
|
||||
/* Standard DCC CHAT... let's listen for incoming connections */
|
||||
handle = dcc_listen(net_sendbuffer_handle(server->handle),
|
||||
&own_ip, &port);
|
||||
if (handle == NULL)
|
||||
channel =
|
||||
dcc_listen_channel(net_sendbuffer_channel(server->handle), &own_ip, &port);
|
||||
if (channel == NULL)
|
||||
cmd_param_error(CMDERR_ERRNO);
|
||||
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
dcc->tagconn =
|
||||
i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) dcc_chat_listen, dcc);
|
||||
|
||||
/* send the chat request */
|
||||
signal_emit("dcc request send", 1, dcc);
|
||||
|
|
@ -645,7 +642,7 @@ static void ctcp_msg_dcc_chat(IRC_SERVER_REC *server, const char *data,
|
|||
|
||||
dcc = DCC_CHAT(dcc_find_request(DCC_CHAT_TYPE, nick, NULL));
|
||||
if (dcc != NULL) {
|
||||
if (dcc_is_listening(dcc)) {
|
||||
if (dcc_is_listening_channel(dcc)) {
|
||||
/* we requested dcc chat, they requested
|
||||
dcc chat from us .. allow it. */
|
||||
dcc_destroy(DCC(dcc));
|
||||
|
|
|
|||
|
|
@ -102,8 +102,7 @@ void dcc_get_send_received(GET_DCC_REC *dcc)
|
|||
memcpy(dcc->count_buf, &recd, 4);
|
||||
|
||||
dcc->count_pos =
|
||||
net_transmit(dcc->handle, dcc->count_buf+dcc->count_pos,
|
||||
4-dcc->count_pos);
|
||||
net_transmit_channel(dcc->channel, dcc->count_buf + dcc->count_pos, 4 - dcc->count_pos);
|
||||
if (dcc->count_pos == 4) dcc->count_pos = 0;
|
||||
|
||||
/* count_pos might be -1 here. if this happens, the
|
||||
|
|
@ -112,7 +111,7 @@ void dcc_get_send_received(GET_DCC_REC *dcc)
|
|||
never, but I just want to do it right.. :) */
|
||||
if (dcc->tagwrite == -1) {
|
||||
dcc->tagwrite =
|
||||
i_input_add(dcc->handle, I_INPUT_WRITE, (GInputFunction) sig_dccget_send, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_WRITE, (GInputFunction) sig_dccget_send, dcc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,8 +122,8 @@ static void sig_dccget_send(GET_DCC_REC *dcc)
|
|||
int ret;
|
||||
|
||||
if (dcc->count_pos != 0) {
|
||||
ret = net_transmit(dcc->handle, dcc->count_buf+dcc->count_pos,
|
||||
4-dcc->count_pos);
|
||||
ret = net_transmit_channel(dcc->channel, dcc->count_buf + dcc->count_pos,
|
||||
4 - dcc->count_pos);
|
||||
|
||||
if (dcc->count_pos <= 0)
|
||||
dcc->count_pos = ret;
|
||||
|
|
@ -157,8 +156,8 @@ static void sig_dccget_receive(GET_DCC_REC *dcc)
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
ret = net_receive(dcc->handle, dcc_get_recv_buffer,
|
||||
DCC_GET_RECV_BUFFER_SIZE);
|
||||
ret = net_receive_channel(dcc->channel, dcc_get_recv_buffer,
|
||||
DCC_GET_RECV_BUFFER_SIZE);
|
||||
if (ret == 0) break;
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
@ -194,7 +193,7 @@ void sig_dccget_connected(GET_DCC_REC *dcc)
|
|||
int ret, ret_errno, temphandle, old_umask;
|
||||
|
||||
if (!dcc->from_dccserver) {
|
||||
if (net_geterror(dcc->handle) != 0) {
|
||||
if (net_geterror_channel(dcc->channel) != 0) {
|
||||
/* error connecting */
|
||||
signal_emit("dcc error connect", 1, dcc);
|
||||
dcc_destroy(DCC(dcc));
|
||||
|
|
@ -285,13 +284,13 @@ void sig_dccget_connected(GET_DCC_REC *dcc)
|
|||
return;
|
||||
}
|
||||
dcc->tagread =
|
||||
i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) sig_dccget_receive, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) sig_dccget_receive, dcc);
|
||||
signal_emit("dcc connected", 1, dcc);
|
||||
|
||||
if (dcc->from_dccserver) {
|
||||
str = g_strdup_printf("121 %s %d\n",
|
||||
dcc->server ? dcc->server->nick : "??", 0);
|
||||
net_transmit(dcc->handle, str, strlen(str));
|
||||
net_transmit_channel(dcc->channel, str, strlen(str));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -307,10 +306,10 @@ void dcc_get_connect(GET_DCC_REC *dcc)
|
|||
return;
|
||||
}
|
||||
|
||||
dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port);
|
||||
dcc->channel = dcc_connect_ip_channel(&dcc->addr, dcc->port);
|
||||
|
||||
if (dcc->handle != NULL) {
|
||||
dcc->tagconn = i_input_add(dcc->handle, I_INPUT_WRITE | I_INPUT_READ,
|
||||
if (dcc->channel != NULL) {
|
||||
dcc->tagconn = i_input_add(dcc->channel, I_INPUT_WRITE | I_INPUT_READ,
|
||||
(GInputFunction) sig_dccget_connected, dcc);
|
||||
} else {
|
||||
/* error connecting */
|
||||
|
|
@ -321,43 +320,43 @@ void dcc_get_connect(GET_DCC_REC *dcc)
|
|||
|
||||
static void dcc_get_listen(GET_DCC_REC *dcc)
|
||||
{
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
IPADDR addr;
|
||||
int port;
|
||||
|
||||
/* accept connection */
|
||||
handle = net_accept(dcc->handle, &addr, &port);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_channel(dcc->channel, &addr, &port);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
|
||||
net_disconnect(dcc->handle);
|
||||
net_disconnect_channel(dcc->channel);
|
||||
g_source_remove(dcc->tagconn);
|
||||
dcc->tagconn = -1;
|
||||
|
||||
dcc->starttime = time(NULL);
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
memcpy(&dcc->addr, &addr, sizeof(IPADDR));
|
||||
net_ip2host(&dcc->addr, dcc->addrstr);
|
||||
dcc->port = port;
|
||||
|
||||
dcc->tagconn = i_input_add(handle, I_INPUT_READ | I_INPUT_WRITE,
|
||||
dcc->tagconn = i_input_add(channel, I_INPUT_READ | I_INPUT_WRITE,
|
||||
(GInputFunction) sig_dccget_connected, dcc);
|
||||
}
|
||||
|
||||
void dcc_get_passive(GET_DCC_REC *dcc)
|
||||
{
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
IPADDR own_ip;
|
||||
int port;
|
||||
char host[MAX_IP_LEN];
|
||||
|
||||
handle = dcc_listen(net_sendbuffer_handle(dcc->server->handle),
|
||||
&own_ip, &port);
|
||||
if (handle == NULL)
|
||||
channel = dcc_listen_channel(net_sendbuffer_channel(dcc->server->handle), &own_ip, &port);
|
||||
if (channel == NULL)
|
||||
cmd_return_error(CMDERR_ERRNO);
|
||||
|
||||
dcc->handle = handle;
|
||||
dcc->tagconn = i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_get_listen, dcc);
|
||||
dcc->channel = channel;
|
||||
dcc->tagconn =
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) dcc_get_listen, dcc);
|
||||
|
||||
/* Let's send the reply to the other client! */
|
||||
dcc_ip2str(&own_ip, host);
|
||||
|
|
@ -581,7 +580,7 @@ void cmd_dcc_receive(const char *data, DCC_GET_FUNC accept_func,
|
|||
|
||||
next = tmp->next;
|
||||
if (IS_DCC_GET(dcc) && g_ascii_strcasecmp(dcc->nick, nick) == 0 &&
|
||||
(dcc_is_waiting_user(dcc) || dcc->from_dccserver) &&
|
||||
(dcc_is_waiting_user_channel(dcc) || dcc->from_dccserver) &&
|
||||
(*fname == '\0' || g_strcmp0(dcc->arg, fname) == 0)) {
|
||||
found = TRUE;
|
||||
if (!dcc_is_passive(dcc))
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ IPADDR addr; /* address we're connected in */
|
|||
char addrstr[MAX_IP_LEN]; /* in readable form */
|
||||
int port; /* port we're connected in */
|
||||
|
||||
GIOChannel *handle; /* socket handle */
|
||||
GIOChannel *channel; /* socket handle */
|
||||
int tagconn, tagread, tagwrite;
|
||||
time_t starttime; /* transfer start time */
|
||||
uoff_t transfd; /* bytes transferred */
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ static void dcc_send_data(SEND_DCC_REC *dcc)
|
|||
return;
|
||||
}
|
||||
|
||||
ret = net_transmit(dcc->handle, buffer, ret);
|
||||
ret = net_transmit_channel(dcc->channel, buffer, ret);
|
||||
if (ret > 0) dcc->transfd += ret;
|
||||
dcc->gotalldata = FALSE;
|
||||
|
||||
|
|
@ -287,8 +287,8 @@ static void dcc_send_read_size(SEND_DCC_REC *dcc)
|
|||
guint32 bytes;
|
||||
int ret;
|
||||
|
||||
ret = net_receive(dcc->handle, dcc->count_buf+dcc->count_pos,
|
||||
4-dcc->count_pos);
|
||||
ret =
|
||||
net_receive_channel(dcc->channel, dcc->count_buf + dcc->count_pos, 4 - dcc->count_pos);
|
||||
if (ret == -1) {
|
||||
dcc_close(DCC(dcc));
|
||||
return;
|
||||
|
|
@ -313,31 +313,31 @@ static void dcc_send_read_size(SEND_DCC_REC *dcc)
|
|||
/* input function: DCC SEND - someone tried to connect to our socket */
|
||||
static void dcc_send_connected(SEND_DCC_REC *dcc)
|
||||
{
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
IPADDR addr;
|
||||
int port;
|
||||
|
||||
/* accept connection */
|
||||
handle = net_accept(dcc->handle, &addr, &port);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_channel(dcc->channel, &addr, &port);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
|
||||
/* TODO: some kind of paranoia check would be nice. it would check
|
||||
that the host of the nick who we sent the request matches the
|
||||
address who connected us. */
|
||||
|
||||
net_disconnect(dcc->handle);
|
||||
net_disconnect_channel(dcc->channel);
|
||||
g_source_remove(dcc->tagconn);
|
||||
dcc->tagconn = -1;
|
||||
|
||||
dcc->starttime = time(NULL);
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
memcpy(&dcc->addr, &addr, sizeof(IPADDR));
|
||||
net_ip2host(&dcc->addr, dcc->addrstr);
|
||||
dcc->port = port;
|
||||
|
||||
dcc->tagread = i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_send_read_size, dcc);
|
||||
dcc->tagwrite = i_input_add(handle, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc);
|
||||
dcc->tagread = i_input_add(channel, I_INPUT_READ, (GInputFunction) dcc_send_read_size, dcc);
|
||||
dcc->tagwrite = i_input_add(channel, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc);
|
||||
|
||||
signal_emit("dcc connected", 1, dcc);
|
||||
}
|
||||
|
|
@ -345,15 +345,15 @@ static void dcc_send_connected(SEND_DCC_REC *dcc)
|
|||
/* input function: DCC SEND - connect to the receiver (passive protocol) */
|
||||
static void dcc_send_connect(SEND_DCC_REC *dcc)
|
||||
{
|
||||
dcc->handle = dcc_connect_ip(&dcc->addr, dcc->port);
|
||||
dcc->channel = dcc_connect_ip_channel(&dcc->addr, dcc->port);
|
||||
|
||||
if (dcc->handle != NULL) {
|
||||
if (dcc->channel != NULL) {
|
||||
dcc->starttime = time(NULL);
|
||||
|
||||
dcc->tagread = i_input_add(dcc->handle, I_INPUT_READ,
|
||||
dcc->tagread = i_input_add(dcc->channel, I_INPUT_READ,
|
||||
(GInputFunction) dcc_send_read_size, dcc);
|
||||
dcc->tagwrite =
|
||||
i_input_add(dcc->handle, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_WRITE, (GInputFunction) dcc_send_data, dcc);
|
||||
signal_emit("dcc connected", 1, dcc);
|
||||
} else {
|
||||
/* error connecting */
|
||||
|
|
@ -372,7 +372,7 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
|
|||
int hfile, port = 0;
|
||||
SEND_DCC_REC *dcc;
|
||||
IPADDR own_ip;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
|
||||
if (dcc_find_request(DCC_SEND_TYPE, target, fname)) {
|
||||
signal_emit("dcc error send exists", 2, target, fname);
|
||||
|
|
@ -398,16 +398,16 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
|
|||
/* start listening (only if passive == FALSE )*/
|
||||
|
||||
if (passive == FALSE) {
|
||||
handle = dcc_listen(chat != NULL ? chat->handle :
|
||||
net_sendbuffer_handle(server->handle),
|
||||
&own_ip, &port);
|
||||
if (handle == NULL) {
|
||||
channel = dcc_listen_channel(chat != NULL ? chat->channel :
|
||||
net_sendbuffer_channel(server->handle),
|
||||
&own_ip, &port);
|
||||
if (channel == NULL) {
|
||||
close(hfile);
|
||||
g_warning("dcc_listen() failed: %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
handle = NULL;
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
str = g_path_get_basename(fname);
|
||||
|
|
@ -425,7 +425,7 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
dcc->port = port;
|
||||
dcc->size = st.st_size;
|
||||
dcc->fhandle = hfile;
|
||||
|
|
@ -433,7 +433,7 @@ static int dcc_send_one_file(int queue, const char *target, const char *fname,
|
|||
dcc->file_quoted = strchr(fname, ' ') != NULL;
|
||||
if (!passive) {
|
||||
dcc->tagconn =
|
||||
i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_send_connected, dcc);
|
||||
i_input_add(channel, I_INPUT_READ, (GInputFunction) dcc_send_connected, dcc);
|
||||
}
|
||||
|
||||
/* Generate an ID for this send if using passive protocol */
|
||||
|
|
|
|||
|
|
@ -49,15 +49,15 @@ static void sig_dcc_destroyed(SERVER_DCC_REC *dcc)
|
|||
}
|
||||
|
||||
/* Start listening for incoming connections */
|
||||
static GIOChannel *dcc_listen_port(GIOChannel *iface, IPADDR *ip, int port)
|
||||
static GIOChannel *dcc_listen_port_channel(GIOChannel *iface, IPADDR *ip, int port)
|
||||
{
|
||||
if (net_getsockname(iface, ip, NULL) == -1)
|
||||
if (net_getsockname_channel(iface, ip, NULL) == -1)
|
||||
return NULL;
|
||||
|
||||
if (IPADDR_IS_V6(ip))
|
||||
return net_listen(NULL, &port);
|
||||
return net_listen_channel(NULL, &port);
|
||||
else
|
||||
return net_listen(&ip4_any, &port);
|
||||
return net_listen_channel(&ip4_any, &port);
|
||||
}
|
||||
|
||||
/* input function: DCC SERVER received some data.. */
|
||||
|
|
@ -85,7 +85,7 @@ static void dcc_server_input(SERVER_DCC_REC *dcc)
|
|||
if (dcc->connection_established) {
|
||||
/* We set handle to NULL first because the new (chat/get) is using the same */
|
||||
/* handle and we don't want dcc_close to disconnect it.*/
|
||||
dcc->handle = NULL;
|
||||
dcc->channel = NULL;
|
||||
dcc_close(DCC(dcc));
|
||||
break;
|
||||
}
|
||||
|
|
@ -164,27 +164,27 @@ static void dcc_server_listen(SERVER_DCC_REC *dcc)
|
|||
{
|
||||
SERVER_DCC_REC *newdcc;
|
||||
IPADDR ip;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
int port;
|
||||
|
||||
g_return_if_fail(IS_DCC_SERVER(dcc));
|
||||
|
||||
/* accept connection */
|
||||
handle = net_accept(dcc->handle, &ip, &port);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_channel(dcc->channel, &ip, &port);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
|
||||
/* Create a new DCC SERVER to handle this connection */
|
||||
newdcc = dcc_server_clone(dcc);
|
||||
|
||||
newdcc->starttime = time(NULL);
|
||||
newdcc->handle = handle;
|
||||
newdcc->sendbuf = net_sendbuffer_create(handle, 0);
|
||||
newdcc->channel = channel;
|
||||
newdcc->sendbuf = net_sendbuffer_create_channel(channel, 0);
|
||||
memcpy(&newdcc->addr, &ip, sizeof(IPADDR));
|
||||
net_ip2host(&newdcc->addr, newdcc->addrstr);
|
||||
newdcc->port = port;
|
||||
newdcc->tagread =
|
||||
i_input_add(handle, I_INPUT_READ, (GInputFunction) dcc_server_input, newdcc);
|
||||
i_input_add(channel, I_INPUT_READ, (GInputFunction) dcc_server_input, newdcc);
|
||||
|
||||
signal_emit("dcc connected", 1, newdcc);
|
||||
}
|
||||
|
|
@ -205,12 +205,12 @@ static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg)
|
|||
CHAT_DCC_REC *dccchat = dcc_chat_create(dcc->server, NULL, msg, "chat");
|
||||
|
||||
dccchat->starttime = time(NULL);
|
||||
dccchat->handle = dcc->handle;
|
||||
dccchat->sendbuf = net_sendbuffer_create(dccchat->handle, 0);
|
||||
dccchat->channel = dcc->channel;
|
||||
dccchat->sendbuf = net_sendbuffer_create_channel(dccchat->channel, 0);
|
||||
memcpy(&dccchat->addr, &dcc->addr, sizeof(IPADDR));
|
||||
net_ip2host(&dccchat->addr, dccchat->addrstr);
|
||||
dccchat->port = dcc->port;
|
||||
dccchat->tagread = i_input_add(dccchat->handle, I_INPUT_READ,
|
||||
dccchat->tagread = i_input_add(dccchat->channel, I_INPUT_READ,
|
||||
(GInputFunction) dcc_chat_input, dccchat);
|
||||
|
||||
dcc->connection_established = 1;
|
||||
|
|
@ -266,7 +266,7 @@ static void dcc_server_msg(SERVER_DCC_REC *dcc, const char *msg)
|
|||
}
|
||||
|
||||
dccget = dcc_get_create(dcc->server, NULL, nick, fname);
|
||||
dccget->handle = dcc->handle;
|
||||
dccget->channel = dcc->channel;
|
||||
dccget->target = g_strdup(dcc->server ? dcc->server->nick : "??");
|
||||
memcpy(&dccget->addr, &dcc->addr, sizeof(dcc->addr));
|
||||
if (dccget->addr.family == AF_INET) {
|
||||
|
|
@ -314,7 +314,7 @@ SERVER_DCC_REC *dcc_server_find_port(const char *port_str)
|
|||
static void cmd_dcc_server(const char *data, IRC_SERVER_REC *server)
|
||||
{
|
||||
void *free_arg;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
SERVER_DCC_REC *dcc;
|
||||
IPADDR own_ip;
|
||||
char *flags, *port;
|
||||
|
|
@ -337,18 +337,18 @@ static void cmd_dcc_server(const char *data, IRC_SERVER_REC *server)
|
|||
cmd_param_error(CMDERR_NOT_CONNECTED);
|
||||
}
|
||||
|
||||
handle = dcc_listen_port(net_sendbuffer_handle(server->handle),
|
||||
&own_ip, atoi(port));
|
||||
channel =
|
||||
dcc_listen_port_channel(net_sendbuffer_channel(server->handle), &own_ip, atoi(port));
|
||||
|
||||
if (handle == NULL) {
|
||||
if (channel == NULL) {
|
||||
cmd_param_error(CMDERR_ERRNO);
|
||||
}
|
||||
|
||||
dcc = dcc_server_create(server, flags);
|
||||
dcc->handle = handle;
|
||||
dcc->channel = channel;
|
||||
dcc->port = atoi(port);
|
||||
dcc->tagconn =
|
||||
i_input_add(dcc->handle, I_INPUT_READ, (GInputFunction) dcc_server_listen, dcc);
|
||||
i_input_add(dcc->channel, I_INPUT_READ, (GInputFunction) dcc_server_listen, dcc);
|
||||
|
||||
signal_emit("dcc server started", 1, dcc);
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,8 @@ void dcc_destroy(DCC_REC *dcc)
|
|||
dcc->destroyed = TRUE;
|
||||
signal_emit("dcc destroyed", 1, dcc);
|
||||
|
||||
if (dcc->handle != NULL) net_disconnect(dcc->handle);
|
||||
if (dcc->channel != NULL)
|
||||
net_disconnect_channel(dcc->channel);
|
||||
if (dcc->tagconn != -1) g_source_remove(dcc->tagconn);
|
||||
if (dcc->tagread != -1) g_source_remove(dcc->tagread);
|
||||
if (dcc->tagwrite != -1) g_source_remove(dcc->tagwrite);
|
||||
|
|
@ -132,7 +133,7 @@ DCC_REC *dcc_find_request_latest(int type)
|
|||
for (tmp = dcc_conns; tmp != NULL; tmp = tmp->next) {
|
||||
DCC_REC *dcc = tmp->data;
|
||||
|
||||
if (dcc->type == type && dcc_is_waiting_user(dcc))
|
||||
if (dcc->type == type && dcc_is_waiting_user_channel(dcc))
|
||||
latest = dcc;
|
||||
}
|
||||
|
||||
|
|
@ -195,14 +196,14 @@ void dcc_str2ip(const char *str, IPADDR *ip)
|
|||
}
|
||||
|
||||
/* Start listening for incoming connections */
|
||||
GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port)
|
||||
GIOChannel *dcc_listen_channel(GIOChannel *iface, IPADDR *ip, int *port)
|
||||
{
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
IPADDR *listen_ip = NULL;
|
||||
const char *dcc_port, *p, *own_ip;
|
||||
int first, last;
|
||||
|
||||
if (net_getsockname(iface, ip, NULL) == -1)
|
||||
if (net_getsockname_channel(iface, ip, NULL) == -1)
|
||||
return NULL;
|
||||
|
||||
/* figure out if we want to listen in IPv4 address or in "any" address,
|
||||
|
|
@ -222,7 +223,7 @@ GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port)
|
|||
if (first == 0) {
|
||||
/* random port */
|
||||
*port = 0;
|
||||
return net_listen(listen_ip, port);
|
||||
return net_listen_channel(listen_ip, port);
|
||||
}
|
||||
|
||||
/* get last port */
|
||||
|
|
@ -240,20 +241,20 @@ GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port)
|
|||
|
||||
/* use the first available port */
|
||||
for (*port = first; *port <= last; (*port)++) {
|
||||
handle = net_listen(listen_ip, port);
|
||||
if (handle != NULL)
|
||||
return handle;
|
||||
channel = net_listen_channel(listen_ip, port);
|
||||
if (channel != NULL)
|
||||
return channel;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Connect to specified IP address using the correct own_ip. */
|
||||
GIOChannel *dcc_connect_ip(IPADDR *ip, int port)
|
||||
GIOChannel *dcc_connect_ip_channel(IPADDR *ip, int port)
|
||||
{
|
||||
IPADDR *own_ip, temp_ip;
|
||||
const char *own_ip_str;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
|
||||
own_ip_str = settings_get_str("dcc_own_ip");
|
||||
own_ip = NULL;
|
||||
|
|
@ -267,13 +268,13 @@ GIOChannel *dcc_connect_ip(IPADDR *ip, int port)
|
|||
if (own_ip == NULL)
|
||||
own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4;
|
||||
|
||||
handle = net_connect_ip(ip, port, own_ip);
|
||||
if (handle == NULL && errno == EADDRNOTAVAIL && own_ip != NULL) {
|
||||
channel = net_connect_ip_channel(ip, port, own_ip);
|
||||
if (channel == NULL && errno == EADDRNOTAVAIL && own_ip != NULL) {
|
||||
/* dcc_own_ip is external address */
|
||||
own_ip = IPADDR_IS_V6(ip) ? source_host_ip6 : source_host_ip4;
|
||||
handle = net_connect_ip(ip, port, own_ip);
|
||||
channel = net_connect_ip_channel(ip, port, own_ip);
|
||||
}
|
||||
return handle;
|
||||
return channel;
|
||||
}
|
||||
|
||||
/* Server connected - update server for DCC records that have
|
||||
|
|
|
|||
|
|
@ -17,12 +17,10 @@ typedef struct {
|
|||
((dcc)->starttime != 0)
|
||||
|
||||
/* not connected, we're waiting for other side to connect */
|
||||
#define dcc_is_listening(dcc) \
|
||||
((dcc)->handle != NULL && (dcc)->starttime == 0)
|
||||
#define dcc_is_listening_channel(dcc) ((dcc)->channel != NULL && (dcc)->starttime == 0)
|
||||
|
||||
/* not connected, waiting for user to accept it */
|
||||
#define dcc_is_waiting_user(dcc) \
|
||||
((dcc)->handle == NULL)
|
||||
#define dcc_is_waiting_user_channel(dcc) ((dcc)->channel == NULL)
|
||||
|
||||
/* passive DCC */
|
||||
#define dcc_is_passive(dcc) \
|
||||
|
|
@ -52,9 +50,9 @@ void dcc_ip2str(IPADDR *ip, char *str);
|
|||
void dcc_str2ip(const char *str, IPADDR *ip);
|
||||
|
||||
/* Start listening for incoming connections */
|
||||
GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port);
|
||||
GIOChannel *dcc_listen_channel(GIOChannel *iface, IPADDR *ip, int *port);
|
||||
/* Connect to specified IP address using the correct own_ip. */
|
||||
GIOChannel *dcc_connect_ip(IPADDR *ip, int port);
|
||||
GIOChannel *dcc_connect_ip_channel(IPADDR *ip, int port);
|
||||
|
||||
/* Close DCC - sends "dcc closed" signal and calls dcc_destroy() */
|
||||
void dcc_close(DCC_REC *dcc);
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static int is_all_digits(const char *s)
|
|||
return strspn(s, "0123456789") == strlen(s);
|
||||
}
|
||||
|
||||
static GIOChannel *net_listen_unix(const char *path)
|
||||
static GIOChannel *net_listen_unix_channel(const char *path)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int saved_errno, handle;
|
||||
|
|
@ -84,16 +84,16 @@ error_close:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static GIOChannel *net_accept_unix(GIOChannel *handle)
|
||||
static GIOChannel *net_accept_unix_channel(GIOChannel *channel)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
int ret;
|
||||
socklen_t addrlen;
|
||||
|
||||
g_return_val_if_fail(handle != NULL, NULL);
|
||||
g_return_val_if_fail(channel != NULL, NULL);
|
||||
|
||||
addrlen = sizeof sa;
|
||||
ret = accept(g_io_channel_unix_get_fd(handle), (struct sockaddr *)&sa, &addrlen);
|
||||
ret = accept(g_io_channel_unix_get_fd(channel), (struct sockaddr *) &sa, &addrlen);
|
||||
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
|
@ -431,7 +431,7 @@ static void sig_listen(LISTEN_REC *listen)
|
|||
CLIENT_REC *rec;
|
||||
IPADDR ip;
|
||||
NET_SENDBUF_REC *sendbuf;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
char host[MAX_IP_LEN];
|
||||
int port;
|
||||
char *addr;
|
||||
|
|
@ -440,20 +440,20 @@ static void sig_listen(LISTEN_REC *listen)
|
|||
|
||||
/* accept connection */
|
||||
if (listen->port) {
|
||||
handle = net_accept(listen->handle, &ip, &port);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_channel(listen->channel, &ip, &port);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
net_ip2host(&ip, host);
|
||||
addr = g_strdup_printf("%s:%d", host, port);
|
||||
} else {
|
||||
/* no port => this is a unix socket */
|
||||
handle = net_accept_unix(listen->handle);
|
||||
if (handle == NULL)
|
||||
channel = net_accept_unix_channel(listen->channel);
|
||||
if (channel == NULL)
|
||||
return;
|
||||
addr = g_strdup("(local)");
|
||||
}
|
||||
|
||||
sendbuf = net_sendbuffer_create(handle, 0);
|
||||
sendbuf = net_sendbuffer_create_channel(channel, 0);
|
||||
rec = g_new0(CLIENT_REC, 1);
|
||||
rec->listen = listen;
|
||||
rec->handle = sendbuf;
|
||||
|
|
@ -470,7 +470,7 @@ static void sig_listen(LISTEN_REC *listen)
|
|||
rec->server = servers == NULL ? NULL :
|
||||
IRC_SERVER(server_find_chatnet(listen->ircnet));
|
||||
}
|
||||
rec->recv_tag = i_input_add(handle, I_INPUT_READ, (GInputFunction) sig_listen_client, rec);
|
||||
rec->recv_tag = i_input_add(channel, I_INPUT_READ, (GInputFunction) sig_listen_client, rec);
|
||||
|
||||
proxy_clients = g_slist_prepend(proxy_clients, rec);
|
||||
listen->clients = g_slist_prepend(listen->clients, rec);
|
||||
|
|
@ -699,14 +699,14 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path)
|
|||
{
|
||||
LISTEN_REC *rec;
|
||||
IPADDR ip4, ip6, *my_ip;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
|
||||
if (*port_or_path == '\0' || port < 0 || *ircnet == '\0')
|
||||
return;
|
||||
|
||||
if (port == 0) {
|
||||
/* listening on a unix socket */
|
||||
handle = net_listen_unix(port_or_path);
|
||||
channel = net_listen_unix_channel(port_or_path);
|
||||
} else {
|
||||
/* bind to specific host/ip? */
|
||||
my_ip = NULL;
|
||||
|
|
@ -725,10 +725,10 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path)
|
|||
&ip6 :
|
||||
&ip4;
|
||||
}
|
||||
handle = net_listen(my_ip, &port);
|
||||
channel = net_listen_channel(my_ip, &port);
|
||||
}
|
||||
|
||||
if (handle == NULL) {
|
||||
if (channel == NULL) {
|
||||
printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
|
||||
"Proxy: Listen in port %s failed: %s",
|
||||
port_or_path, g_strerror(errno));
|
||||
|
|
@ -736,12 +736,12 @@ static void add_listen(const char *ircnet, int port, const char *port_or_path)
|
|||
}
|
||||
|
||||
rec = g_new0(LISTEN_REC, 1);
|
||||
rec->handle = handle;
|
||||
rec->channel = channel;
|
||||
rec->ircnet = g_strdup(ircnet);
|
||||
rec->port = port;
|
||||
rec->port_or_path = g_strdup(port_or_path);
|
||||
|
||||
rec->tag = i_input_add(rec->handle, I_INPUT_READ, (GInputFunction) sig_listen, rec);
|
||||
rec->tag = i_input_add(rec->channel, I_INPUT_READ, (GInputFunction) sig_listen, rec);
|
||||
|
||||
proxy_listens = g_slist_append(proxy_listens, rec);
|
||||
}
|
||||
|
|
@ -757,7 +757,7 @@ static void remove_listen(LISTEN_REC *rec)
|
|||
if (rec->port == 0)
|
||||
unlink(rec->port_or_path);
|
||||
|
||||
net_disconnect(rec->handle);
|
||||
net_disconnect_channel(rec->channel);
|
||||
g_source_remove(rec->tag);
|
||||
g_free(rec->port_or_path);
|
||||
g_free(rec->ircnet);
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ typedef struct {
|
|||
char *ircnet;
|
||||
|
||||
int tag;
|
||||
GIOChannel *handle;
|
||||
GIOChannel *channel;
|
||||
|
||||
GSList *clients;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue