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/libircclient.c
./libircclient/src/params.h
./libircclient/src/portable.h
./libircclient/src/portable.c
./libircclient/src/session.h
./libircclient/src/sockets.c
./libircclient/src/sockets.h
./libircclient/src/ssl.h
./libircclient/src/ssl.c
./libircclient/src/utils.c
./libircclient/src/utils.h
)
target_include_directories(libircclient PUBLIC ./libircclient/include)

View File

@ -16,6 +16,11 @@
#define LIBIRC_DCC_SENDFILE 2
#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)
{
@ -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 )
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;
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
* to provide some data.
*/
* to provide some data.
*/
if ( dcc->state == LIBIRC_STATE_CONNECTED
&& dcc->dccmode == LIBIRC_DCC_SENDFILE
&& 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:
/*
* 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,
* then RECEIVER should confirm the packet, so we have to receive
* data.
*
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
* can't change asynchronously.
*/
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
libirc_add_to_set (dcc->sock, out_set, maxfd);
* 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
* data.
*
* We don't need to LOCK_DCC_OUTBUF - during file transfer, buffers
* can't change asynchronously.
*/
if ( dcc->dccmode == LIBIRC_DCC_RECVFILE && dcc->outgoing_offset > 0 )
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);
}
}
@ -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;
/*
* 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);
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
* callbacks (except there is an error). We just receive
* the data, and compare it with the amount sent.
*/
* callbacks (except there is an error). We just receive
* the data, and compare it with the amount sent.
*/
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE )
{
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
* (which is smaller than offset). Otherwise we send
* a full buffer.
*/
* a full buffer.
*/
libirc_mutex_unlock (&ircsession->mutex_dcc);
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);
/*
* If the session is not terminated in callback,
* put the sent amount into the sent_packet_size_net_byteorder
*/
if ( dcc->state != LIBIRC_STATE_REMOVED )
{
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
dcc->file_confirm_offset += offset;
/*
* If the session is not terminated in callback,
* put the sent amount into the sent_packet_size_net_byteorder
*/
if ( dcc->state != LIBIRC_STATE_REMOVED )
{
dcc->state = LIBIRC_STATE_CONFIRM_SIZE;
dcc->file_confirm_offset += offset;
// Store as big endian
dcc->outgoing_buf[0] = (char) dcc->file_confirm_offset >> 24;
dcc->outgoing_buf[1] = (char) dcc->file_confirm_offset >> 16;
dcc->outgoing_buf[2] = (char) dcc->file_confirm_offset >> 8;
dcc->outgoing_buf[3] = (char) dcc->file_confirm_offset;
dcc->outgoing_offset = 4;
dcc->outgoing_offset = 4;
}
}
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
* of failure, and destroy this session.
*/
/*
* If error arises somewhere above, we inform the caller
* of failure, and destroy this session.
*/
if ( err )
{
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
* processing, so before out_set processing we should check
* for this case
/*
* Session might be closed (with sock = -1) after the in_set
* processing, so before out_set processing we should check
* for this case
*/
if ( dcc->state == LIBIRC_STATE_REMOVED )
continue;
/*
* Write bit set - we can send() something, and it won't block.
*/
*/
if ( FD_ISSET (dcc->sock, out_set) )
{
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
* asynchronously (by another thread), we should lock
* it.
*/
*/
libirc_mutex_lock (&dcc->mutex_outbuf);
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,
* change the state to wait for confirmation (and store
* sent packet size)
*/
*/
if ( dcc->state == LIBIRC_STATE_CONNECTED
&& 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
* back.
*/
*/
if ( dcc->state == LIBIRC_STATE_CONFIRM_SIZE
&& dcc->dccmode == LIBIRC_DCC_RECVFILE
&& dcc->outgoing_offset == 0 )
{
/*
* 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 )
{
{
libirc_mutex_unlock (&ircsession->mutex_dcc);
libirc_mutex_unlock (&dcc->mutex_outbuf);
(*dcc->cb)(ircsession, dcc->id, 0, dcc->ctx, 0, 0);
libirc_dcc_destroy_nolock (ircsession, dcc->id);
}
else
{
/* Continue to receive the file */
}
else
{
/* Continue to receive the file */
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);
/*
* If error arises somewhere above, we inform the caller
* of failure, and destroy this session.
*/
/*
* If error arises somewhere above, we inform the caller
* of failure, and destroy this session.
*/
if ( err )
{
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));
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_port = htons(port);
dcc->remote_addr.sin_port = htons(port);
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);
*pdcc = dcc;
return 0;
*pdcc = dcc;
return 0;
cleanup_exit_error:
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];
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;
// 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_mutex_unlock (&session->mutex_dcc);

View File

@ -15,6 +15,13 @@
#ifndef 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.
@ -27,10 +34,10 @@ struct irc_dcc_session_s
void * ctx;
socket_t sock; /*!< DCC socket */
int dccmode; /*!< Boolean value to differ chat vs send
requests. Changes the cb behavior - when
it is chat, data is sent by lines with
stripped CRLFs. In file mode, the data
is sent as-is */
requests. Changes the cb behavior - when
it is chat, data is sent by lines with
stripped CRLFs. In file mode, the data
is sent as-is */
int state;
time_t timeout;
@ -50,5 +57,9 @@ struct irc_dcc_session_s
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 */

View File

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

View File

@ -14,17 +14,19 @@
#define IS_DEBUG_ENABLED(s) ((s)->options & LIBIRC_OPTION_DEBUG)
#include "portable.c"
#include "sockets.c"
#include "./portable.h"
#include "./sockets.h"
#include "libircclient.h"
#include "session.h"
#include "../include/libircclient.h"
#include "./session.h"
#include "utils.c"
#include "errors.c"
#include "colors.c"
#include "dcc.c"
#include "ssl.c"
#include "./utils.h"
/*#include "errors.c"*/
/*#include "colors.c"*/
#include "./dcc.h"
/*#include "dcc.c"*/
/*#include "ssl.c"*/
#include "./ssl.h"
#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 */
}
else
else
{
/*
* The "unknown" event is triggered upon receipt of any number of

View File

@ -12,121 +12,7 @@
* License for more details.
*/
#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
#include "./portable.h"
/*
* 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
#include "params.h"
#include "dcc.h"
#include "libirc_events.h"
#include "./params.h"
#include "./dcc.h"
#include "../include/libirc_events.h"
// Session flags

View File

@ -12,6 +12,9 @@
* 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.
*/
@ -159,3 +162,5 @@ static int socket_send (socket_t * sock, const void *buf, size_t len)
return length;
}
#endif /* INCLUDE_IRC_SOCKET_H */

View File

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