more fixes, should work now

This commit is contained in:
Green Sky 2023-11-23 00:01:55 +01:00
parent 3b3b50b7ec
commit 3bf7660b85
No known key found for this signature in database
12 changed files with 428 additions and 341 deletions

View File

@ -17,11 +17,13 @@ add_library(libircclient
./libircclient/src/errors.c ./libircclient/src/errors.c
./libircclient/src/libircclient.c ./libircclient/src/libircclient.c
./libircclient/src/params.h ./libircclient/src/params.h
./libircclient/src/portable.h
./libircclient/src/portable.c ./libircclient/src/portable.c
./libircclient/src/session.h ./libircclient/src/session.h
./libircclient/src/sockets.c ./libircclient/src/sockets.h
./libircclient/src/ssl.h
./libircclient/src/ssl.c ./libircclient/src/ssl.c
./libircclient/src/utils.c ./libircclient/src/utils.h
) )
target_include_directories(libircclient PUBLIC ./libircclient/include) target_include_directories(libircclient PUBLIC ./libircclient/include)

View File

@ -16,6 +16,11 @@
#define LIBIRC_DCC_SENDFILE 2 #define LIBIRC_DCC_SENDFILE 2
#define LIBIRC_DCC_RECVFILE 3 #define LIBIRC_DCC_RECVFILE 3
#include "./session.h"
#include "./utils.h"
#include <stdio.h>
#include <string.h>
static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc_dcc_t dccid, int lock_list) static irc_dcc_session_t * libirc_find_dcc_session (irc_session_t * session, irc_dcc_t dccid, int lock_list)
{ {
@ -54,7 +59,7 @@ static void libirc_dcc_destroy_nolock (irc_session_t * session, irc_dcc_t dccid)
} }
static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list) void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list)
{ {
if ( dcc->sock >= 0 ) if ( dcc->sock >= 0 )
socket_close (&dcc->sock); socket_close (&dcc->sock);
@ -91,7 +96,7 @@ static void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_
} }
static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd) void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd)
{ {
irc_dcc_session_t * dcc, *dcc_next; irc_dcc_session_t * dcc, *dcc_next;
time_t now = time (0); time_t now = time (0);
@ -129,8 +134,8 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
/* /*
* If we're sending file, and the output buffer is empty, we need * If we're sending file, and the output buffer is empty, we need
* to provide some data. * to provide some data.
*/ */
if ( dcc->state == LIBIRC_STATE_CONNECTED if ( dcc->state == LIBIRC_STATE_CONNECTED
&& dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->dccmode == LIBIRC_DCC_SENDFILE
&& dcc->dccsend_file_fp && dcc->dccsend_file_fp
@ -189,17 +194,17 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
case LIBIRC_STATE_CONFIRM_SIZE: case LIBIRC_STATE_CONFIRM_SIZE:
/* /*
* If we're receiving file, then WE should confirm the transferred * If we're receiving file, then WE should confirm the transferred
* part (so we have to sent data). But if we're sending the file, * part (so we have to sent data). But if we're sending the file,
* then RECEIVER should confirm the packet, so we have to receive * then RECEIVER should confirm the packet, so we have to receive
* data. * data.
* *
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers * We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
* can't change asynchronously. * can't change asynchronously.
*/ */
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 ) if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
libirc_add_to_set (dcc->sock, out_set, maxfd); libirc_add_to_set (dcc->sock, out_set, maxfd);
if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 ) if ( dcc->dccmode == LIBIRC_DCC_SENDFILE && dcc->incoming_offset < 4 )
libirc_add_to_set (dcc->sock, in_set, maxfd); libirc_add_to_set (dcc->sock, in_set, maxfd);
} }
} }
@ -208,14 +213,14 @@ static void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_s
} }
static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set) void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set)
{ {
irc_dcc_session_t * dcc; irc_dcc_session_t * dcc;
/* /*
* We need to use such a complex scheme here, because on every callback * We need to use such a complex scheme here, because on every callback
* a number of DCC sessions could be destroyed. * a number of DCC sessions could be destroyed.
*/ */
libirc_mutex_lock (&ircsession->mutex_dcc); libirc_mutex_lock (&ircsession->mutex_dcc);
for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next ) for ( dcc = ircsession->dcc_sessions; dcc; dcc = dcc->next )
@ -325,9 +330,9 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
/* /*
* In LIBIRC_STATE_CONFIRM_SIZE state we don't call any * In LIBIRC_STATE_CONFIRM_SIZE state we don't call any
* callbacks (except there is an error). We just receive * callbacks (except there is an error). We just receive
* the data, and compare it with the amount sent. * the data, and compare it with the amount sent.
*/ */
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE ) if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
{ {
if ( dcc->dccmode != LIBIRC_DCC_SENDFILE ) if ( dcc->dccmode != LIBIRC_DCC_SENDFILE )
@ -354,8 +359,8 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
/* /*
* If it is DCC_CHAT, we send a 0-terminated string * If it is DCC_CHAT, we send a 0-terminated string
* (which is smaller than offset). Otherwise we send * (which is smaller than offset). Otherwise we send
* a full buffer. * a full buffer.
*/ */
libirc_mutex_unlock (&ircsession->mutex_dcc); libirc_mutex_unlock (&ircsession->mutex_dcc);
if ( dcc->dccmode != LIBIRC_DCC_CHAT ) if ( dcc->dccmode != LIBIRC_DCC_CHAT )
@ -365,21 +370,21 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
(*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset); (*dcc->cb)(ircsession, dcc->id, err, dcc->ctx, dcc->incoming_buf, offset);
/* /*
* If the session is not terminated in callback, * If the session is not terminated in callback,
* put the sent amount into the sent_packet_size_net_byteorder * put the sent amount into the sent_packet_size_net_byteorder
*/ */
if ( dcc->state != LIBIRC_STATE_REMOVED ) if ( dcc->state != LIBIRC_STATE_REMOVED )
{ {
dcc->state = LIBIRC_STATE_CONFIRM_SIZE; dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
dcc->file_confirm_offset += offset; dcc->file_confirm_offset += offset;
// Store as big endian // Store as big endian
dcc->outgoing_buf[0] = (char) dcc->file_confirm_offset >> 24; dcc->outgoing_buf[0] = (char) dcc->file_confirm_offset >> 24;
dcc->outgoing_buf[1] = (char) dcc->file_confirm_offset >> 16; dcc->outgoing_buf[1] = (char) dcc->file_confirm_offset >> 16;
dcc->outgoing_buf[2] = (char) dcc->file_confirm_offset >> 8; dcc->outgoing_buf[2] = (char) dcc->file_confirm_offset >> 8;
dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset; dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset;
dcc->outgoing_offset = 4; dcc->outgoing_offset = 4;
} }
} }
else else
@ -394,10 +399,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
} }
} }
/* /*
* If error arises somewhere above, we inform the caller * If error arises somewhere above, we inform the caller
* of failure, and destroy this session. * of failure, and destroy this session.
*/ */
if ( err ) if ( err )
{ {
libirc_mutex_unlock (&ircsession->mutex_dcc); libirc_mutex_unlock (&ircsession->mutex_dcc);
@ -407,17 +412,17 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
} }
} }
/* /*
* Session might be closed (with sock = -1) after the in_set * Session might be closed (with sock = -1) after the in_set
* processing, so before out_set processing we should check * processing, so before out_set processing we should check
* for this case * for this case
*/ */
if ( dcc->state == LIBIRC_STATE_REMOVED ) if ( dcc->state == LIBIRC_STATE_REMOVED )
continue; continue;
/* /*
* Write bit set - we can send() something, and it won't block. * Write bit set - we can send() something, and it won't block.
*/ */
if ( FD_ISSET (dcc->sock, out_set) ) if ( FD_ISSET (dcc->sock, out_set) )
{ {
int length, offset, err = 0; int length, offset, err = 0;
@ -426,7 +431,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
* Because in some cases outgoing_buf could be changed * Because in some cases outgoing_buf could be changed
* asynchronously (by another thread), we should lock * asynchronously (by another thread), we should lock
* it. * it.
*/ */
libirc_mutex_lock (&dcc->mutex_outbuf); libirc_mutex_lock (&dcc->mutex_outbuf);
offset = dcc->outgoing_offset; offset = dcc->outgoing_offset;
@ -445,7 +450,7 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
* If this was DCC_SENDFILE, and we just sent a packet, * If this was DCC_SENDFILE, and we just sent a packet,
* change the state to wait for confirmation (and store * change the state to wait for confirmation (and store
* sent packet size) * sent packet size)
*/ */
if ( dcc->state == LIBIRC_STATE_CONNECTED if ( dcc->state == LIBIRC_STATE_CONNECTED
&& dcc->dccmode == LIBIRC_DCC_SENDFILE ) && dcc->dccmode == LIBIRC_DCC_SENDFILE )
{ {
@ -467,25 +472,25 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
/* /*
* If we just sent the confirmation data, change state * If we just sent the confirmation data, change state
* back. * back.
*/ */
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE
&& dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->dccmode == LIBIRC_DCC_RECVFILE
&& dcc->outgoing_offset == 0 ) && dcc->outgoing_offset == 0 )
{ {
/* /*
* If the file is already received, we should inform * If the file is already received, we should inform
* the caller, and close the session. * the caller, and close the session.
*/ */
if ( dcc->received_file_size == dcc->file_confirm_offset ) if ( dcc->received_file_size == dcc->file_confirm_offset )
{ {
libirc_mutex_unlock (&ircsession->mutex_dcc); libirc_mutex_unlock (&ircsession->mutex_dcc);
libirc_mutex_unlock (&dcc->mutex_outbuf); libirc_mutex_unlock (&dcc->mutex_outbuf);
(*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0); (*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0);
libirc_dcc_destroy_nolock (ircsession, dcc->id); libirc_dcc_destroy_nolock (ircsession, dcc->id);
} }
else else
{ {
/* Continue to receive the file */ /* Continue to receive the file */
dcc->state = LIBIRC_STATE_CONNECTED; dcc->state = LIBIRC_STATE_CONNECTED;
} }
} }
@ -494,10 +499,10 @@ static void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *
libirc_mutex_unlock (&dcc->mutex_outbuf); libirc_mutex_unlock (&dcc->mutex_outbuf);
/* /*
* If error arises somewhere above, we inform the caller * If error arises somewhere above, we inform the caller
* of failure, and destroy this session. * of failure, and destroy this session.
*/ */
if ( err ) if ( err )
{ {
libirc_mutex_unlock (&ircsession->mutex_dcc); libirc_mutex_unlock (&ircsession->mutex_dcc);
@ -578,7 +583,7 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr)); memset (&dcc->remote_addr, 0, sizeof(dcc->remote_addr));
dcc->remote_addr.sin_family = AF_INET; dcc->remote_addr.sin_family = AF_INET;
dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder? dcc->remote_addr.sin_addr.s_addr = htonl (ip); // what idiot came up with idea to send IP address in host-byteorder?
dcc->remote_addr.sin_port = htons(port); dcc->remote_addr.sin_port = htons(port);
dcc->state = LIBIRC_STATE_INIT; dcc->state = LIBIRC_STATE_INIT;
} }
@ -596,8 +601,8 @@ static int libirc_new_dcc_session (irc_session_t * session, unsigned long ip, un
libirc_mutex_unlock (&session->mutex_dcc); libirc_mutex_unlock (&session->mutex_dcc);
*pdcc = dcc; *pdcc = dcc;
return 0; return 0;
cleanup_exit_error: cleanup_exit_error:
if ( dcc->sock >= 0 ) if ( dcc->sock >= 0 )
@ -710,7 +715,7 @@ int irc_dcc_msg (irc_session_t * session, irc_dcc_t dccid, const char * text)
} }
static void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req) void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req)
{ {
char filenamebuf[256]; char filenamebuf[256];
unsigned long ip, size; unsigned long ip, size;
@ -787,7 +792,7 @@ int irc_dcc_accept (irc_session_t * session, irc_dcc_t dccid, void * ctx, irc_dc
dcc->ctx = ctx; dcc->ctx = ctx;
// Initiate the connect // Initiate the connect
if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) ) if ( socket_connect (&dcc->sock, (struct sockaddr *) &dcc->remote_addr, sizeof(dcc->remote_addr)) )
{ {
libirc_dcc_destroy_nolock (session, dccid); libirc_dcc_destroy_nolock (session, dccid);
libirc_mutex_unlock (&session->mutex_dcc); libirc_mutex_unlock (&session->mutex_dcc);

View File

@ -15,6 +15,13 @@
#ifndef INCLUDE_IRC_DCC_H #ifndef INCLUDE_IRC_DCC_H
#define INCLUDE_IRC_DCC_H #define INCLUDE_IRC_DCC_H
#include <stdio.h>
#include "../include/libircclient.h"
#include "./sockets.h"
#include "./portable.h"
#include "./params.h"
/* /*
* This structure keeps the state of a single DCC connection. * This structure keeps the state of a single DCC connection.
@ -27,10 +34,10 @@ struct irc_dcc_session_s
void * ctx; void * ctx;
socket_t sock; /*!< DCC socket */ socket_t sock; /*!< DCC socket */
int dccmode; /*!< Boolean value to differ chat vs send int dccmode; /*!< Boolean value to differ chat vs send
requests. Changes the cb behavior - when requests. Changes the cb behavior - when
it is chat, data is sent by lines with it is chat, data is sent by lines with
stripped CRLFs. In file mode, the data stripped CRLFs. In file mode, the data
is sent as-is */ is sent as-is */
int state; int state;
time_t timeout; time_t timeout;
@ -50,5 +57,9 @@ struct irc_dcc_session_s
irc_dcc_callback_t cb; irc_dcc_callback_t cb;
}; };
void libirc_remove_dcc_session (irc_session_t * session, irc_dcc_session_t * dcc, int lock_list);
void libirc_dcc_add_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set, int * maxfd);
void libirc_dcc_request (irc_session_t * session, const char * nick, const char * req);
void libirc_dcc_process_descriptors (irc_session_t * ircsession, fd_set *in_set, fd_set *out_set);
#endif /* INCLUDE_IRC_DCC_H */ #endif /* INCLUDE_IRC_DCC_H */

View File

@ -12,6 +12,9 @@
* License for more details. * License for more details.
*/ */
#include "../include/libircclient.h"
#include "./session.h"
static const char * libirc_strerror[LIBIRC_ERR_MAX] = static const char * libirc_strerror[LIBIRC_ERR_MAX] =
{ {
"No error", "No error",

View File

@ -14,17 +14,19 @@
#define IS_DEBUG_ENABLED(s) ((s)->options & LIBIRC_OPTION_DEBUG) #define IS_DEBUG_ENABLED(s) ((s)->options & LIBIRC_OPTION_DEBUG)
#include "portable.c" #include "./portable.h"
#include "sockets.c" #include "./sockets.h"
#include "libircclient.h" #include "../include/libircclient.h"
#include "session.h" #include "./session.h"
#include "utils.c" #include "./utils.h"
#include "errors.c" /*#include "errors.c"*/
#include "colors.c" /*#include "colors.c"*/
#include "dcc.c" #include "./dcc.h"
#include "ssl.c" /*#include "dcc.c"*/
/*#include "ssl.c"*/
#include "./ssl.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -797,7 +799,7 @@ static void libirc_process_incoming_data (irc_session_t * session, size_t proces
{ {
; /* ignore this event - not all servers generate this */ ; /* ignore this event - not all servers generate this */
} }
else else
{ {
/* /*
* The "unknown" event is triggered upon receipt of any number of * The "unknown" event is triggered upon receipt of any number of

View File

@ -12,121 +12,7 @@
* License for more details. * License for more details.
*/ */
#if !defined (_WIN32) #include "./portable.h"
#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#if defined (ENABLE_THREADS)
#include <pthread.h>
typedef pthread_mutex_t port_mutex_t;
#if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP)
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
#endif
#endif
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#if defined (ENABLE_THREADS)
typedef CRITICAL_SECTION port_mutex_t;
#endif
#define inline
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strncasecmp _strnicmp
#endif
#if defined (ENABLE_SSL)
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#endif
#if defined (ENABLE_THREADS)
static inline int libirc_mutex_init (port_mutex_t * mutex)
{
#if defined (_WIN32)
InitializeCriticalSection (mutex);
return 0;
#elif defined (PTHREAD_MUTEX_RECURSIVE)
pthread_mutexattr_t attr;
return (pthread_mutexattr_init (&attr)
|| pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)
|| pthread_mutex_init (mutex, &attr));
#else /* !defined (PTHREAD_MUTEX_RECURSIVE) */
return pthread_mutex_init (mutex, 0);
#endif /* defined (_WIN32) */
}
static inline void libirc_mutex_destroy (port_mutex_t * mutex)
{
#if defined (_WIN32)
DeleteCriticalSection (mutex);
#else
pthread_mutex_destroy (mutex);
#endif
}
static inline void libirc_mutex_lock (port_mutex_t * mutex)
{
#if defined (_WIN32)
EnterCriticalSection (mutex);
#else
pthread_mutex_lock (mutex);
#endif
}
static inline void libirc_mutex_unlock (port_mutex_t * mutex)
{
#if defined (_WIN32)
LeaveCriticalSection (mutex);
#else
pthread_mutex_unlock (mutex);
#endif
}
#else
typedef void * port_mutex_t;
static inline int libirc_mutex_init (port_mutex_t * mutex) { return 0; }
static inline void libirc_mutex_destroy (port_mutex_t * mutex) {}
static inline void libirc_mutex_lock (port_mutex_t * mutex) {}
static inline void libirc_mutex_unlock (port_mutex_t * mutex) {}
#endif
/* /*
* Stub for WIN32 dll to initialize winsock API * Stub for WIN32 dll to initialize winsock API

133
libircclient/src/portable.h Normal file
View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#ifndef INCLUDE_IRC_PORTABLE_H
#define INCLUDE_IRC_PORTABLE_H
#if !defined (_WIN32)
//#include "config.h"
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#if defined (ENABLE_THREADS)
#include <pthread.h>
typedef pthread_mutex_t port_mutex_t;
#if !defined (PTHREAD_MUTEX_RECURSIVE) && defined (PTHREAD_MUTEX_RECURSIVE_NP)
#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
#endif
#endif
#else
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#if defined (ENABLE_THREADS)
typedef CRITICAL_SECTION port_mutex_t;
#endif
#define inline
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#define strncasecmp _strnicmp
#endif
#if defined (ENABLE_SSL)
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#endif
#if defined (ENABLE_THREADS)
static inline int libirc_mutex_init (port_mutex_t * mutex)
{
#if defined (_WIN32)
InitializeCriticalSection (mutex);
return 0;
#elif defined (PTHREAD_MUTEX_RECURSIVE)
pthread_mutexattr_t attr;
return (pthread_mutexattr_init (&attr)
|| pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE)
|| pthread_mutex_init (mutex, &attr));
#else /* !defined (PTHREAD_MUTEX_RECURSIVE) */
return pthread_mutex_init (mutex, 0);
#endif /* defined (_WIN32) */
}
static inline void libirc_mutex_destroy (port_mutex_t * mutex)
{
#if defined (_WIN32)
DeleteCriticalSection (mutex);
#else
pthread_mutex_destroy (mutex);
#endif
}
static inline void libirc_mutex_lock (port_mutex_t * mutex)
{
#if defined (_WIN32)
EnterCriticalSection (mutex);
#else
pthread_mutex_lock (mutex);
#endif
}
static inline void libirc_mutex_unlock (port_mutex_t * mutex)
{
#if defined (_WIN32)
LeaveCriticalSection (mutex);
#else
pthread_mutex_unlock (mutex);
#endif
}
#else
typedef void * port_mutex_t;
static inline int libirc_mutex_init (port_mutex_t * mutex) { return 0; }
static inline void libirc_mutex_destroy (port_mutex_t * mutex) {}
static inline void libirc_mutex_lock (port_mutex_t * mutex) {}
static inline void libirc_mutex_unlock (port_mutex_t * mutex) {}
#endif
#endif /* INCLUDE_IRC_PORTABLE_H */

View File

@ -17,9 +17,9 @@
#define INCLUDE_IRC_SESSION_H #define INCLUDE_IRC_SESSION_H
#include "params.h" #include "./params.h"
#include "dcc.h" #include "./dcc.h"
#include "libirc_events.h" #include "../include/libirc_events.h"
// Session flags // Session flags

View File

@ -12,6 +12,9 @@
* License for more details. * License for more details.
*/ */
#ifndef INCLUDE_IRC_SOCKET_H
#define INCLUDE_IRC_SOCKET_H
/* /*
* The sockets interface was moved out to simplify going OpenSSL integration. * The sockets interface was moved out to simplify going OpenSSL integration.
*/ */
@ -159,3 +162,5 @@ static int socket_send (socket_t * sock, const void *buf, size_t len)
return length; return length;
} }
#endif /* INCLUDE_IRC_SOCKET_H */

View File

@ -12,6 +12,10 @@
* License for more details. * License for more details.
*/ */
#include "./ssl.h"
#include "../include/libircclient.h"
#include "./session.h"
#if defined (ENABLE_SSL) #if defined (ENABLE_SSL)
@ -26,16 +30,16 @@ static CRITICAL_SECTION * mutex_buf = 0;
// OpenSSL callback to utilize static locks // OpenSSL callback to utilize static locks
static void cb_openssl_locking_function( int mode, int n, const char * file, int line ) static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
{ {
if ( mode & CRYPTO_LOCK) if ( mode & CRYPTO_LOCK)
EnterCriticalSection( &mutex_buf[n] ); EnterCriticalSection( &mutex_buf[n] );
else else
LeaveCriticalSection( &mutex_buf[n] ); LeaveCriticalSection( &mutex_buf[n] );
} }
// OpenSSL callback to get the thread ID // OpenSSL callback to get the thread ID
static unsigned long cb_openssl_id_function(void) static unsigned long cb_openssl_id_function(void)
{ {
return ((unsigned long) GetCurrentThreadId() ); return ((unsigned long) GetCurrentThreadId() );
} }
static int alloc_mutexes( unsigned int total ) static int alloc_mutexes( unsigned int total )
@ -63,13 +67,13 @@ static pthread_mutex_t * mutex_buf = 0;
// OpenSSL callback to utilize static locks // OpenSSL callback to utilize static locks
static void cb_openssl_locking_function( int mode, int n, const char * file, int line ) static void cb_openssl_locking_function( int mode, int n, const char * file, int line )
{ {
(void)file; (void)file;
(void)line; (void)line;
if ( mode & CRYPTO_LOCK) if ( mode & CRYPTO_LOCK)
pthread_mutex_lock( &mutex_buf[n] ); pthread_mutex_lock( &mutex_buf[n] );
else else
pthread_mutex_unlock( &mutex_buf[n] ); pthread_mutex_unlock( &mutex_buf[n] );
} }
// OpenSSL callback to get the thread ID // OpenSSL callback to get the thread ID
@ -252,7 +256,7 @@ static int ssl_recv( irc_session_t * session )
// Read up to m_bufferLength bytes // Read up to m_bufferLength bytes
count = SSL_read( session->ssl, session->incoming_buf + session->incoming_offset, amount ); count = SSL_read( session->ssl, session->incoming_buf + session->incoming_offset, amount );
if ( count > 0 ) if ( count > 0 )
return count; return count;
else if ( count == 0 ) else if ( count == 0 )
return -1; // remote connection closed return -1; // remote connection closed
@ -261,20 +265,20 @@ static int ssl_recv( irc_session_t * session )
int ssl_error = SSL_get_error( session->ssl, count ); int ssl_error = SSL_get_error( session->ssl, count );
// Handle SSL error since not all of them are actually errors // Handle SSL error since not all of them are actually errors
switch ( ssl_error ) switch ( ssl_error )
{ {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
// This is not really an error. We received something, but // This is not really an error. We received something, but
// OpenSSL gave nothing to us because all it read was // OpenSSL gave nothing to us because all it read was
// internal data. Repeat the same read. // internal data. Repeat the same read.
return 0; return 0;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
// This is not really an error. We received something, but // This is not really an error. We received something, but
// now OpenSSL needs to send the data before returning any // now OpenSSL needs to send the data before returning any
// data to us (like negotiations). This means we'd need // data to us (like negotiations). This means we'd need
// to wait for WRITE event, but call SSL_read() again. // to wait for WRITE event, but call SSL_read() again.
session->flags |= SESSIONFL_SSL_READ_WANTS_WRITE; session->flags |= SESSIONFL_SSL_READ_WANTS_WRITE;
return 0; return 0;
} }
@ -289,37 +293,37 @@ static int ssl_recv( irc_session_t * session )
static int ssl_send( irc_session_t * session ) static int ssl_send( irc_session_t * session )
{ {
int count; int count;
ERR_clear_error(); ERR_clear_error();
count = SSL_write( session->ssl, session->outgoing_buf, session->outgoing_offset ); count = SSL_write( session->ssl, session->outgoing_buf, session->outgoing_offset );
if ( count > 0 ) if ( count > 0 )
return count; return count;
else if ( count == 0 ) else if ( count == 0 )
return -1; return -1;
else else
{ {
int ssl_error = SSL_get_error( session->ssl, count ); int ssl_error = SSL_get_error( session->ssl, count );
switch ( ssl_error ) switch ( ssl_error )
{ {
case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_READ:
// This is not really an error. We sent some internal OpenSSL data, // This is not really an error. We sent some internal OpenSSL data,
// but now it needs to read more data before it can send anything. // but now it needs to read more data before it can send anything.
// Thus we wait for READ event, but will call SSL_write() again. // Thus we wait for READ event, but will call SSL_write() again.
session->flags |= SESSIONFL_SSL_WRITE_WANTS_READ; session->flags |= SESSIONFL_SSL_WRITE_WANTS_READ;
return 0; return 0;
case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_WRITE:
// This is not really an error. We sent some data, but now OpenSSL // This is not really an error. We sent some data, but now OpenSSL
// wants to send some internal data before sending ours. // wants to send some internal data before sending ours.
// Repeat the same write. // Repeat the same write.
return 0; return 0;
} }
// This is an SSL error, handle it // This is an SSL error, handle it
ssl_handle_error( session, ERR_get_error() ); ssl_handle_error( session, ERR_get_error() );
} }
return -1; return -1;
} }
@ -331,7 +335,7 @@ static int ssl_send( irc_session_t * session )
// Returns -1 in case there is an error and socket should be closed/connection terminated // Returns -1 in case there is an error and socket should be closed/connection terminated
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case) // Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
// Returns a positive number if we actually read something // Returns a positive number if we actually read something
static int session_socket_read( irc_session_t * session ) int session_socket_read( irc_session_t * session )
{ {
int length; int length;
@ -352,7 +356,7 @@ static int session_socket_read( irc_session_t * session )
length = socket_recv( &session->sock, length = socket_recv( &session->sock,
session->incoming_buf + session->incoming_offset, session->incoming_buf + session->incoming_offset,
(sizeof (session->incoming_buf) - 1) - session->incoming_offset ); (sizeof (session->incoming_buf) - 1) - session->incoming_offset );
// There is no "retry" errors for regular sockets // There is no "retry" errors for regular sockets
if ( length <= 0 ) if ( length <= 0 )
@ -365,7 +369,7 @@ static int session_socket_read( irc_session_t * session )
// Returns -1 in case there is an error and socket should be closed/connection terminated // Returns -1 in case there is an error and socket should be closed/connection terminated
// Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case) // Returns 0 in case there is a temporary error and the call should be retried (SSL_WANTS_WRITE case)
// Returns a positive number if we actually sent something // Returns a positive number if we actually sent something
static int session_socket_write( irc_session_t * session ) int session_socket_write( irc_session_t * session )
{ {
int length; int length;

23
libircclient/src/ssl.h Normal file
View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2004-2012 George Yunaev gyunaev@ulduzsoft.com
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*/
#include "./session.h"
#ifndef INCLUDE_IRC_SSL_H
#define INCLUDE_IRC_SSL_H
int session_socket_read( irc_session_t * session );
int session_socket_write( irc_session_t * session );
#endif /* INCLUDE_IRC_SSL_H */

View File

@ -12,6 +12,17 @@
* License for more details. * License for more details.
*/ */
#ifndef INCLUDE_IRC_UTILS_H
#define INCLUDE_IRC_UTILS_H
//#include <sys/select.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "./session.h"
static void libirc_add_to_set (int fd, fd_set *set, int * maxfd) static void libirc_add_to_set (int fd, fd_set *set, int * maxfd)
{ {
FD_SET (fd, set); FD_SET (fd, set);
@ -128,3 +139,5 @@ static void libirc_event_ctcp_internal (irc_session_t * session, const char * ev
} }
} }
} }
#endif /* INCLUDE_IRC_UTILS_H */