Kannel: Open Source WAP and SMS gateway  svn-r5335
conn.c File Reference
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include "gwlib/gwlib.h"

Go to the source code of this file.

Data Structures

struct  Connection
 

Macros

#define DEFAULT_OUTPUT_BUFFERING   0
 
#define SSL_CONN_TIMEOUT   30
 
#define unlock_in(conn)   unlock_in_real(conn, __FILE__, __LINE__, __func__)
 
#define unlock_out(conn)   unlock_out_real(conn, __FILE__, __LINE__, __func__)
 

Typedefs

typedef unsigned long(* CRYPTO_CALLBACK_PTR) (void)
 

Functions

static void unlocked_register_pollin (Connection *conn, int onoff)
 
static void unlocked_register_pollout (Connection *conn, int onoff)
 
static void lock_in (Connection *conn)
 
static void unlock_in_real (Connection *conn, char *file, int line, const char *func)
 
static void lock_out (Connection *conn)
 
static void unlock_out_real (Connection *conn, char *file, int line, const char *func)
 
static long unlocked_outbuf_len (Connection *conn)
 
static long unlocked_inbuf_len (Connection *conn)
 
static long unlocked_write (Connection *conn)
 
static int unlocked_try_write (Connection *conn)
 
static void unlocked_read (Connection *conn)
 
static Octstrunlocked_get (Connection *conn, long length)
 
Connectionconn_open_tcp (Octstr *host, int port, Octstr *our_host)
 
Connectionconn_open_tcp_nb (Octstr *host, int port, Octstr *our_host)
 
Connectionconn_open_tcp_nb_with_port (Octstr *host, int port, int our_port, Octstr *our_host)
 
int conn_is_connected (Connection *conn)
 
int conn_get_connect_result (Connection *conn)
 
Connectionconn_open_tcp_with_port (Octstr *host, int port, int our_port, Octstr *our_host)
 
Connectionconn_wrap_fd (int fd, int ssl)
 
void conn_destroy (Connection *conn)
 
void conn_claim (Connection *conn)
 
long conn_outbuf_len (Connection *conn)
 
long conn_inbuf_len (Connection *conn)
 
int conn_eof (Connection *conn)
 
int conn_error (Connection *conn)
 
void conn_set_output_buffering (Connection *conn, unsigned int size)
 
static void poll_callback (int fd, int revents, void *data)
 
int conn_register_real (Connection *conn, FDSet *fdset, conn_callback_t callback, void *data, conn_callback_data_destroyer_t *data_destroyer)
 
void conn_unregister (Connection *conn)
 
int conn_wait (Connection *conn, double seconds)
 
int conn_flush (Connection *conn)
 
int conn_write (Connection *conn, Octstr *data)
 
int conn_write_data (Connection *conn, unsigned char *data, long length)
 
int conn_write_withlen (Connection *conn, Octstr *data)
 
Octstrconn_read_everything (Connection *conn)
 
Octstrconn_read_fixed (Connection *conn, long length)
 
Octstrconn_read_line (Connection *conn)
 
Octstrconn_read_withlen (Connection *conn)
 
Octstrconn_read_packet (Connection *conn, int startmark, int endmark)
 
void conn_config_ssl (CfgGroup *grp)
 
int conn_get_id (Connection *conn)
 

Macro Definition Documentation

◆ DEFAULT_OUTPUT_BUFFERING

#define DEFAULT_OUTPUT_BUFFERING   0

Definition at line 103 of file conn.c.

Referenced by conn_wrap_fd().

◆ SSL_CONN_TIMEOUT

#define SSL_CONN_TIMEOUT   30

Definition at line 104 of file conn.c.

◆ unlock_in

#define unlock_in (   conn)    unlock_in_real(conn, __FILE__, __LINE__, __func__)

◆ unlock_out

#define unlock_out (   conn)    unlock_out_real(conn, __FILE__, __LINE__, __func__)

Typedef Documentation

◆ CRYPTO_CALLBACK_PTR

typedef unsigned long(* CRYPTO_CALLBACK_PTR) (void)

Definition at line 94 of file conn.c.

Function Documentation

◆ conn_claim()

void conn_claim ( Connection conn)

Definition at line 671 of file conn.c.

References Connection::claimed, Connection::claiming_thread, gw_assert(), gwthread_self(), and panic.

Referenced by cgw_listener(), emi2_listener(), and fake_listener().

672 {
673  gw_assert(conn != NULL);
674 
675  if (conn->claimed)
676  panic(0, "Connection is being claimed twice!");
677  conn->claimed = 1;
678 #ifndef NO_GWASSERT
679  conn->claiming_thread = gwthread_self();
680 #endif
681 }
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
long claiming_thread
Definition: conn.c:115
volatile sig_atomic_t claimed
Definition: conn.c:113
#define panic
Definition: log.h:87

◆ conn_config_ssl()

void conn_config_ssl ( CfgGroup grp)

Definition at line 1546 of file conn.c.

References info().

Referenced by init_bearerbox(), init_smppbox(), init_smsbox(), init_sqlbox(), and init_wapbox().

1547 {
1548  info(0, "SSL not supported, no SSL initialization done.");
1549 }
void info(int err, const char *fmt,...)
Definition: log.c:672

◆ conn_destroy()

void conn_destroy ( Connection conn)

Definition at line 627 of file conn.c.

References Connection::callback_data, Connection::callback_data_destroyer, error(), Connection::fd, fdset_unregister(), Connection::inbuf, Connection::inlock, mutex_destroy(), octstr_destroy(), Connection::outbuf, Connection::outlock, Connection::registered, and unlocked_try_write().

Referenced by boxc_destroy(), cgw_listener(), cgw_open_send_connection(), cgw_sender(), client_destroy(), close_connection_to_bearerbox_real(), conn_pool_get(), conn_pool_item_destroy(), conn_wrap_fd(), emi2_idleprocessing(), emi2_idletimeout_handling(), emi2_listener(), emi2_sender(), esme_destroy(), get_connection(), handle_transaction(), io_thread(), main(), main_connection_loop(), open_receiver(), open_send_connection(), open_transceiver(), open_transmitter(), send_request(), smasi_thread(), smpp_emu(), and smsbox_thread().

628 {
629  int ret;
630 
631  if (conn == NULL)
632  return;
633 
634  /* No locking done here. conn_destroy should not be called
635  * if any thread might still be interested in the connection. */
636 
637  if (conn->registered) {
638  fdset_unregister(conn->registered, conn->fd);
639  /* call data destroyer if any */
640  if (conn->callback_data != NULL && conn->callback_data_destroyer != NULL)
642  }
643 
644  if (conn->fd >= 0) {
645  /* Try to flush any remaining data */
646  unlocked_try_write(conn);
647 
648 #ifdef HAVE_LIBSSL
649  if (conn->ssl != NULL) {
650  SSL_smart_shutdown(conn->ssl);
651  SSL_free(conn->ssl);
652  if (conn->peer_certificate != NULL)
653  X509_free(conn->peer_certificate);
654  }
655 #endif /* HAVE_LIBSSL */
656 
657  ret = close(conn->fd);
658  if (ret < 0)
659  error(errno, "conn_destroy: error on close");
660  conn->fd = -1;
661  }
662 
663  octstr_destroy(conn->outbuf);
664  octstr_destroy(conn->inbuf);
665  mutex_destroy(conn->inlock);
666  mutex_destroy(conn->outlock);
667 
668  gw_free(conn);
669 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static int unlocked_try_write(Connection *conn)
Definition: conn.c:289
Mutex * outlock
Definition: conn.c:112
FDSet * registered
Definition: conn.c:141
void * callback_data
Definition: conn.c:143
Octstr * outbuf
Definition: conn.c:125
void fdset_unregister(FDSet *set, int fd)
Definition: fdset.c:510
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:144
int fd
Definition: conn.c:119
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
Mutex * inlock
Definition: conn.c:111
Octstr * inbuf
Definition: conn.c:133

◆ conn_eof()

◆ conn_error()

int conn_error ( Connection conn)

Definition at line 716 of file conn.c.

References Connection::io_error, lock_in(), lock_out(), unlock_in, and unlock_out.

Referenced by cgw_receiver(), cgw_wait_command(), client_read_status(), conn_pool_get(), emi2_handle_smscreq(), emi2_receiver(), emi2_send_loop(), http_accept_request(), main(), main_connection_loop(), read_body_until_eof(), read_body_with_length(), read_chunked_body_crlf(), read_chunked_body_data(), read_chunked_body_len(), read_from_bearerbox_real(), read_from_box(), read_pdu(), read_some_headers(), receive_request(), receive_smpp_thread(), smpp_emu_reader(), smsbox_thread(), and wait_for_ack().

717 {
718  int err;
719 
720  lock_out(conn);
721  lock_in(conn);
722  err = conn->io_error;
723  unlock_in(conn);
724  unlock_out(conn);
725 
726  return err;
727 }
int io_error
Definition: conn.c:137
static void lock_out(Connection *conn)
Definition: conn.c:197
#define unlock_in(conn)
Definition: conn.c:168
static void lock_in(Connection *conn)
Definition: conn.c:172
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_flush()

int conn_flush ( Connection conn)

Definition at line 995 of file conn.c.

References error(), Connection::fd, gwthread_pollfd(), lock_out(), POLLERR, POLLHUP, POLLNVAL, POLLOUT, unlock_out, unlocked_outbuf_len(), and unlocked_write().

Referenced by boxc_sender().

996 {
997  int ret;
998  int revents;
999  int fd;
1000 
1001  lock_out(conn);
1002  ret = unlocked_write(conn);
1003  if (ret < 0) {
1004  unlock_out(conn);
1005  return -1;
1006  }
1007 
1008  while (unlocked_outbuf_len(conn) != 0) {
1009  fd = conn->fd;
1010 
1011  unlock_out(conn);
1012  revents = gwthread_pollfd(fd, POLLOUT, -1.0);
1013 
1014  /* Note: Make sure we have the "out" lock when
1015  * going through the loop again, because the
1016  * loop condition needs it. */
1017 
1018  if (revents < 0) {
1019  if (errno == EINTR)
1020  return 1;
1021  error(0, "conn_flush: poll failed on fd %d:", fd);
1022  return -1;
1023  }
1024 
1025  if (revents == 0) {
1026  /* We were woken up */
1027  return 1;
1028  }
1029 
1030  if (revents & POLLNVAL) {
1031  error(0, "conn_flush: fd %d not open.", fd);
1032  return -1;
1033  }
1034 
1035  lock_out(conn);
1036 
1037  if (revents & (POLLOUT | POLLERR | POLLHUP)) {
1038  ret = unlocked_write(conn);
1039  if (ret < 0) {
1040  unlock_out(conn);
1041  return -1;
1042  }
1043  }
1044  }
1045 
1046  unlock_out(conn);
1047 
1048  return 0;
1049 }
void error(int err, const char *fmt,...)
Definition: log.c:648
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
#define POLLNVAL
Definition: gwpoll.h:98
static void lock_out(Connection *conn)
Definition: conn.c:197
int fd
Definition: conn.c:119
#define POLLERR
Definition: gwpoll.h:96
int gwthread_pollfd(int fd, int events, double timeout)
static long unlocked_write(Connection *conn)
Definition: conn.c:235
#define unlock_out(conn)
Definition: conn.c:169
#define POLLHUP
Definition: gwpoll.h:97
#define POLLOUT
Definition: gwpoll.h:93

◆ conn_get_connect_result()

int conn_get_connect_result ( Connection conn)

Definition at line 530 of file conn.c.

References Connection::connected, and Connection::fd.

Referenced by handle_transaction().

531 {
532  int err;
533  socklen_t len;
534 
535  len = sizeof(err);
536  if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
537  return -1;
538  }
539 
540  if (err) {
541  return -1;
542  }
543 
544  conn->connected = yes;
545  return 0;
546 }
int fd
Definition: conn.c:119
enum Connection::@56 connected
int socklen_t
Definition: socket.h:73

◆ conn_get_id()

int conn_get_id ( Connection conn)

Definition at line 1552 of file conn.c.

References Connection::fd.

Referenced by conn_pool_get().

1552  {
1553  if(conn == NULL)
1554  return 0;
1555  else
1556  return conn->fd;
1557 }
int fd
Definition: conn.c:119

◆ conn_inbuf_len()

long conn_inbuf_len ( Connection conn)

Definition at line 694 of file conn.c.

References lock_in(), unlock_in, and unlocked_inbuf_len().

695 {
696  long len;
697 
698  lock_in(conn);
699  len = unlocked_inbuf_len(conn);
700  unlock_in(conn);
701 
702  return len;
703 }
#define unlock_in(conn)
Definition: conn.c:168
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:228
static void lock_in(Connection *conn)
Definition: conn.c:172

◆ conn_is_connected()

int conn_is_connected ( Connection conn)

Definition at line 525 of file conn.c.

References Connection::connected.

Referenced by write_request_thread().

526 {
527  return conn->connected == yes ? 0 : -1;
528 }
enum Connection::@56 connected

◆ conn_open_tcp()

Connection* conn_open_tcp ( Octstr host,
int  port,
Octstr our_host 
)

Definition at line 496 of file conn.c.

References conn_open_tcp_with_port(), host, and our_host.

Referenced by connect_to_bearerbox_real(), main(), open_receiver(), open_transceiver(), open_transmitter(), and smsbox_thread().

497 {
499 }
Definition: http.c:2014
static Octstr * host
Definition: fakesmsc.c:122
static Octstr * our_host
Definition: radius_acct.c:86
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:548

◆ conn_open_tcp_nb()

Connection* conn_open_tcp_nb ( Octstr host,
int  port,
Octstr our_host 
)

Definition at line 501 of file conn.c.

References conn_open_tcp_nb_with_port(), host, and our_host.

Referenced by conn_pool_get().

502 {
504 }
Definition: http.c:2014
static Octstr * host
Definition: fakesmsc.c:122
static Octstr * our_host
Definition: radius_acct.c:86
Connection * conn_open_tcp_nb_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:506

◆ conn_open_tcp_nb_with_port()

Connection* conn_open_tcp_nb_with_port ( Octstr host,
int  port,
int  our_port,
Octstr our_host 
)

Definition at line 506 of file conn.c.

References conn_wrap_fd(), Connection::connected, host, octstr_get_cstr, our_host, our_port, sockfd, and tcpip_connect_nb_to_server_with_port().

Referenced by conn_open_tcp_nb().

508 {
509  int sockfd;
510  int done = -1;
511  Connection *c;
512 
514  our_port, our_host == NULL ?
515  NULL : octstr_get_cstr(our_host), &done);
516  if (sockfd < 0)
517  return NULL;
518  c = conn_wrap_fd(sockfd, 0);
519  if (done != 0) {
520  c->connected = no;
521  }
522  return c;
523 }
static long our_port
Definition: radius_acct.c:87
Definition: http.c:2014
static Octstr * host
Definition: fakesmsc.c:122
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * our_host
Definition: radius_acct.c:86
int sockfd
Definition: test_cimd2.c:145
int tcpip_connect_nb_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr, int *done)
Definition: socket.c:246
enum Connection::@56 connected
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ conn_open_tcp_with_port()

Connection* conn_open_tcp_with_port ( Octstr host,
int  port,
int  our_port,
Octstr our_host 
)

Definition at line 548 of file conn.c.

References conn_wrap_fd(), host, octstr_get_cstr, our_host, our_port, sockfd, and tcpip_connect_to_server_with_port().

Referenced by cgw_open_send_connection(), conn_open_tcp(), open_connection(), open_receiver(), open_send_connection(), open_transceiver(), and open_transmitter().

550 {
551  int sockfd;
552 
554  our_port, our_host == NULL ?
555  NULL : octstr_get_cstr(our_host));
556  if (sockfd < 0)
557  return NULL;
558  return conn_wrap_fd(sockfd, 0);
559 }
static long our_port
Definition: radius_acct.c:87
Definition: http.c:2014
static Octstr * host
Definition: fakesmsc.c:122
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static Octstr * our_host
Definition: radius_acct.c:86
int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr)
Definition: socket.c:156
int sockfd
Definition: test_cimd2.c:145
Connection * conn_wrap_fd(int fd, int ssl)
Definition: conn.c:566

◆ conn_outbuf_len()

long conn_outbuf_len ( Connection conn)

Definition at line 683 of file conn.c.

References lock_out(), unlock_out, and unlocked_outbuf_len().

Referenced by receive_request().

684 {
685  long len;
686 
687  lock_out(conn);
688  len = unlocked_outbuf_len(conn);
689  unlock_out(conn);
690 
691  return len;
692 }
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
static void lock_out(Connection *conn)
Definition: conn.c:197
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_read_everything()

Octstr* conn_read_everything ( Connection conn)

Definition at line 1090 of file conn.c.

References lock_in(), unlock_in, unlocked_get(), unlocked_inbuf_len(), and unlocked_read().

Referenced by read_body_until_eof().

1091 {
1092  Octstr *result = NULL;
1093 
1094  lock_in(conn);
1095  if (unlocked_inbuf_len(conn) == 0) {
1096  unlocked_read(conn);
1097  if (unlocked_inbuf_len(conn) == 0) {
1098  unlock_in(conn);
1099  return NULL;
1100  }
1101  }
1102 
1103  result = unlocked_get(conn, unlocked_inbuf_len(conn));
1104  gw_claim_area(result);
1105  unlock_in(conn);
1106 
1107  return result;
1108 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:361
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:228
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:172

◆ conn_read_fixed()

Octstr* conn_read_fixed ( Connection conn,
long  length 
)

Definition at line 1110 of file conn.c.

References lock_in(), unlock_in, unlocked_get(), unlocked_inbuf_len(), and unlocked_read().

Referenced by read_body_with_length(), read_chunked_body_data(), smpp_pdu_read_data(), and smpp_pdu_read_len().

1111 {
1112  Octstr *result = NULL;
1113 
1114  if (length < 1)
1115  return NULL;
1116 
1117  /* See if the data is already available. If not, try a read(),
1118  * then see if we have enough data after that. If not, give up. */
1119  lock_in(conn);
1120  if (unlocked_inbuf_len(conn) < length) {
1121  unlocked_read(conn);
1122  if (unlocked_inbuf_len(conn) < length) {
1123  unlock_in(conn);
1124  return NULL;
1125  }
1126  }
1127  result = unlocked_get(conn, length);
1128  gw_claim_area(result);
1129  unlock_in(conn);
1130 
1131  return result;
1132 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:361
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:228
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:172

◆ conn_read_line()

Octstr* conn_read_line ( Connection conn)

Definition at line 1134 of file conn.c.

References Connection::inbuf, Connection::inbufpos, lock_in(), octstr_delete(), octstr_get_char(), octstr_len(), octstr_search_char(), unlock_in, unlocked_get(), and unlocked_read().

Referenced by cgw_read_op(), client_read_status(), main(), main_connection_loop(), read_chunked_body_crlf(), read_chunked_body_len(), read_some_headers(), receive_request(), and smasi_pdu_read().

1135 {
1136  Octstr *result = NULL;
1137  long pos;
1138 
1139  lock_in(conn);
1140  /* 10 is the code for linefeed. We don't rely on \n because that
1141  * might be a different value on some (strange) systems, and
1142  * we are reading from a network connection. */
1143  pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
1144  if (pos < 0) {
1145  unlocked_read(conn);
1146  pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
1147  if (pos < 0) {
1148  unlock_in(conn);
1149  return NULL;
1150  }
1151  }
1152 
1153  result = unlocked_get(conn, pos - conn->inbufpos);
1154  gw_claim_area(result);
1155 
1156  /* Skip the LF, which we left in the buffer */
1157  conn->inbufpos++;
1158 
1159  /* If the line was terminated with CR LF, we have to remove
1160  * the CR from the result. */
1161  if (octstr_len(result) > 0 &&
1162  octstr_get_char(result, octstr_len(result) - 1) == 13)
1163  octstr_delete(result, octstr_len(result) - 1, 1);
1164 
1165  unlock_in(conn);
1166  return result;
1167 }
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:361
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:172
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:406
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ conn_read_packet()

Octstr* conn_read_packet ( Connection conn,
int  startmark,
int  endmark 
)

Definition at line 1214 of file conn.c.

References endmark(), Connection::inbuf, Connection::inbufpos, lock_in(), octstr_len(), octstr_search_char(), startmark(), unlock_in, unlocked_get(), and unlocked_read().

Referenced by emi2_handle_smscreq(), emi2_receiver(), and wait_for_ack().

1215 {
1216  int startpos, endpos;
1217  Octstr *result = NULL;
1218  int try;
1219 
1220  lock_in(conn);
1221 
1222  for (try = 1; try <= 2; try++) {
1223  if (try > 1)
1224  unlocked_read(conn);
1225 
1226  /* Find startmark, and discard everything up to it */
1227  if (startmark >= 0) {
1228  startpos = octstr_search_char(conn->inbuf, startmark, conn->inbufpos);
1229  if (startpos < 0) {
1230  conn->inbufpos = octstr_len(conn->inbuf);
1231  continue;
1232  } else {
1233  conn->inbufpos = startpos;
1234  }
1235  } else {
1236  startpos = conn->inbufpos;
1237  }
1238 
1239  /* Find first endmark after startmark */
1240  endpos = octstr_search_char(conn->inbuf, endmark, conn->inbufpos);
1241  if (endpos < 0)
1242  continue;
1243 
1244  result = unlocked_get(conn, endpos - startpos + 1);
1245  gw_claim_area(result);
1246  break;
1247  }
1248 
1249  unlock_in(conn);
1250  return result;
1251 }
static void startmark(unsigned char *p, long number)
Definition: gwmem-check.c:263
static void endmark(unsigned char *p, size_t size)
Definition: gwmem-check.c:255
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1012
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:361
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:172
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ conn_read_withlen()

Octstr* conn_read_withlen ( Connection conn)

Definition at line 1169 of file conn.c.

References decode_network_long(), Connection::inbuf, Connection::inbufpos, lock_in(), octstr_get_many_chars(), unlock_in, unlocked_get(), unlocked_inbuf_len(), unlocked_read(), and warning().

Referenced by read_from_bearerbox_real(), read_from_box(), run_requests(), and smsbox_thread().

1170 {
1171  Octstr *result = NULL;
1172  unsigned char lengthbuf[4];
1173  long length = 0; /* for compiler please */
1174  int try, retry;
1175 
1176  lock_in(conn);
1177 
1178  for (try = 1; try <= 2; try++) {
1179  if (try > 1)
1180  unlocked_read(conn);
1181 
1182  do {
1183  retry = 0;
1184  /* First get the length. */
1185  if (unlocked_inbuf_len(conn) < 4)
1186  continue;
1187 
1188  octstr_get_many_chars(lengthbuf, conn->inbuf, conn->inbufpos, 4);
1189  length = decode_network_long(lengthbuf);
1190 
1191  if (length < 0) {
1192  warning(0, "conn_read_withlen: got negative length, skipping");
1193  conn->inbufpos += 4;
1194  retry = 1;
1195  length = 0;
1196  }
1197  } while (retry == 1);
1198 
1199  /* Then get the data, as long as the read size is below
1200  * the indicated length. */
1201  if (unlocked_inbuf_len(conn) - 4 < length)
1202  continue;
1203 
1204  conn->inbufpos += 4;
1205  result = unlocked_get(conn, length);
1206  gw_claim_area(result);
1207  break;
1208  }
1209 
1210  unlock_in(conn);
1211  return result;
1212 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:361
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
void warning(int err, const char *fmt,...)
Definition: log.c:660
long decode_network_long(unsigned char *data)
Definition: utils.c:935
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:228
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:172
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
Definition: octstr.c:425
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ conn_register_real()

int conn_register_real ( Connection conn,
FDSet fdset,
conn_callback_t  callback,
void *  data,
conn_callback_data_destroyer_t data_destroyer 
)

Definition at line 802 of file conn.c.

References Connection::callback, Connection::callback_data, Connection::callback_data_destroyer, Connection::connected, Connection::fd, fdset_register(), gw_assert(), Connection::io_error, Connection::listening_pollin, Connection::listening_pollout, lock_in(), lock_out(), poll_callback(), POLLIN, POLLOUT, Connection::read_eof, Connection::registered, unlock_in, unlock_out, and unlocked_outbuf_len().

804 {
805  int events;
806  int result = 0;
807 
808  gw_assert(conn != NULL);
809 
810  if (conn->fd < 0)
811  return -1;
812 
813  /* We need both locks if we want to update the registration
814  * information. */
815  lock_out(conn);
816  lock_in(conn);
817 
818  if (conn->registered == fdset) {
819  /* Re-registering. Change only the callback info. */
820  conn->callback = callback;
821  /* call data destroyer if new data supplied */
822  if (conn->callback_data != NULL && conn->callback_data != data && conn->callback_data_destroyer != NULL)
824  conn->callback_data = data;
825  conn->callback_data_destroyer = data_destroyer;
826  result = 0;
827  } else if (conn->registered) {
828  /* Already registered to a different fdset. */
829  result = -1;
830  } else {
831  events = 0;
832  /* For nonconnected socket we must lesten both directions */
833  if (conn->connected == yes) {
834  if (conn->read_eof == 0 && conn->io_error == 0)
835  events |= POLLIN;
836  if (unlocked_outbuf_len(conn) > 0)
837  events |= POLLOUT;
838  } else {
839  events |= POLLIN | POLLOUT;
840  }
841 
842  conn->registered = fdset;
843  conn->callback = callback;
844  conn->callback_data = data;
845  conn->callback_data_destroyer = data_destroyer;
846  conn->listening_pollin = (events & POLLIN) != 0;
847  conn->listening_pollout = (events & POLLOUT) != 0;
848  fdset_register(fdset, conn->fd, events, poll_callback, conn);
849  result = 0;
850  }
851 
852  unlock_in(conn);
853  unlock_out(conn);
854 
855  return result;
856 }
int listening_pollout
Definition: conn.c:148
conn_callback_t * callback
Definition: conn.c:142
gw_assert(wtls_machine->packet_to_send !=NULL)
FDSet * registered
Definition: conn.c:141
int read_eof
Definition: conn.c:136
int listening_pollin
Definition: conn.c:146
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
void * callback_data
Definition: conn.c:143
int io_error
Definition: conn.c:137
static void lock_out(Connection *conn)
Definition: conn.c:197
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:144
void fdset_register(FDSet *set, int fd, int events, fdset_callback_t callback, void *data)
Definition: fdset.c:425
#define POLLIN
Definition: gwpoll.h:91
#define unlock_in(conn)
Definition: conn.c:168
int fd
Definition: conn.c:119
static void poll_callback(int fd, int revents, void *data)
Definition: conn.c:738
enum Connection::@56 connected
static void lock_in(Connection *conn)
Definition: conn.c:172
#define unlock_out(conn)
Definition: conn.c:169
#define POLLOUT
Definition: gwpoll.h:93

◆ conn_set_output_buffering()

void conn_set_output_buffering ( Connection conn,
unsigned int  size 
)

Definition at line 729 of file conn.c.

References lock_out(), Connection::output_buffering, size, unlock_out, and unlocked_try_write().

730 {
731  lock_out(conn);
732  conn->output_buffering = size;
733  /* If the buffer size is smaller, we may have to write immediately. */
734  unlocked_try_write(conn);
735  unlock_out(conn);
736 }
int size
Definition: wsasm.c:84
static int unlocked_try_write(Connection *conn)
Definition: conn.c:289
unsigned int output_buffering
Definition: conn.c:130
static void lock_out(Connection *conn)
Definition: conn.c:197
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_unregister()

void conn_unregister ( Connection conn)

Definition at line 858 of file conn.c.

References Connection::callback, Connection::callback_data, Connection::callback_data_destroyer, Connection::fd, fdset_unregister(), gw_assert(), Connection::listening_pollin, Connection::listening_pollout, lock_in(), lock_out(), Connection::registered, unlock_in, and unlock_out.

Referenced by conn_pool_get(), handle_transaction(), port_remove(), and receive_request().

859 {
860  FDSet *set = NULL;
861  int fd = -1;
862  void *data = NULL;
863  conn_callback_data_destroyer_t *destroyer = NULL;
864 
865  gw_assert(conn != NULL);
866 
867  if (conn == NULL || conn->fd < 0)
868  return;
869 
870  /* We need both locks to update the registration information */
871  lock_out(conn);
872  lock_in(conn);
873 
874  if (conn->registered) {
875  set = conn->registered;
876  fd = conn->fd;
877  conn->registered = NULL;
878  conn->callback = NULL;
879  /*
880  * remember and don't destroy data and data_destroyer because we
881  * may be in callback right now. So destroy only after fdset_unregister
882  * call which guarantee us we are not in callback anymore.
883  */
884  data = conn->callback_data;
885  conn->callback_data = NULL;
886  destroyer = conn->callback_data_destroyer;
887  conn->callback_data_destroyer = NULL;
888  conn->listening_pollin = 0;
889  conn->listening_pollout = 0;
890  }
891 
892  unlock_in(conn);
893  unlock_out(conn);
894 
895  /* now unregister from FDSet */
896  if (set != NULL)
897  fdset_unregister(set, fd);
898 
899  /* ok we are not in callback anymore, destroy data if any */
900  if (data != NULL && destroyer != NULL)
901  destroyer(data);
902 }
int listening_pollout
Definition: conn.c:148
conn_callback_t * callback
Definition: conn.c:142
gw_assert(wtls_machine->packet_to_send !=NULL)
FDSet * registered
Definition: conn.c:141
int listening_pollin
Definition: conn.c:146
void * callback_data
Definition: conn.c:143
void fdset_unregister(FDSet *set, int fd)
Definition: fdset.c:510
static void lock_out(Connection *conn)
Definition: conn.c:197
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:144
void conn_callback_data_destroyer_t(void *data)
Definition: conn.h:113
#define unlock_in(conn)
Definition: conn.c:168
int fd
Definition: conn.c:119
static void lock_in(Connection *conn)
Definition: conn.c:172
Definition: fdset.c:70
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_wait()

int conn_wait ( Connection conn,
double  seconds 
)

Definition at line 904 of file conn.c.

References error(), Connection::fd, gwthread_pollfd(), Connection::io_error, lock_in(), lock_out(), POLLERR, POLLHUP, POLLIN, POLLNVAL, POLLOUT, Connection::read_eof, unlock_in, unlock_out, unlocked_outbuf_len(), unlocked_read(), and unlocked_write().

Referenced by cgw_receiver(), cgw_wait_command(), conn_pool_get(), emi2_receiver(), emi2_wait(), http_accept_request(), io_thread(), main(), main_connection_loop(), read_from_bearerbox_real(), read_from_box(), receive_smpp_thread(), run_requests(), smasi_thread(), smpp_emu_reader(), smsbox_thread(), and wait_for_ack().

905 {
906  int events;
907  int ret;
908  int fd;
909 
910  lock_out(conn);
911 
912  /* Try to write any data that might still be waiting to be sent */
913  ret = unlocked_write(conn);
914  if (ret < 0) {
915  unlock_out(conn);
916  return -1;
917  }
918  if (ret > 0) {
919  /* We did something useful. No need to poll or wait now. */
920  unlock_out(conn);
921  return 0;
922  }
923 
924  fd = conn->fd;
925 
926  /* Normally, we block until there is more data available. But
927  * if any data still needs to be sent, we block until we can
928  * send it (or there is more data available). We always block
929  * for reading, unless we know there is no more data coming.
930  * (Because in that case, poll will keep reporting POLLIN to
931  * signal the end of the file). If the caller explicitly wants
932  * to wait even though there is no data to write and we're at
933  * end of file, then poll for new data anyway because the caller
934  * apparently doesn't trust eof. */
935  events = 0;
936  if (unlocked_outbuf_len(conn) > 0)
937  events |= POLLOUT;
938  /* Don't keep the connection locked while we wait */
939  unlock_out(conn);
940 
941  /* We need the in lock to query read_eof */
942  lock_in(conn);
943  if ((conn->read_eof == 0 && conn->io_error == 0) || events == 0)
944  events |= POLLIN;
945  unlock_in(conn);
946 
947  ret = gwthread_pollfd(fd, events, seconds);
948  if (ret < 0) {
949  if (errno == EINTR)
950  return 0;
951  error(0, "conn_wait: poll failed on fd %d:", fd);
952  return -1;
953  }
954 
955  if (ret == 0)
956  return 1;
957 
958  if (ret & POLLNVAL) {
959  error(0, "conn_wait: fd %d not open.", fd);
960  return -1;
961  }
962 
963  if (ret & (POLLERR | POLLHUP)) {
964  /* Call unlocked_read to report the specific error,
965  * and handle the results of the error. We can't be
966  * certain that the error still exists, because we
967  * released the lock for a while. */
968  lock_in(conn);
969  unlocked_read(conn);
970  unlock_in(conn);
971  return -1;
972  }
973 
974  /* If POLLOUT is on, then we must have wanted
975  * to write something. */
976  if (ret & POLLOUT) {
977  lock_out(conn);
978  unlocked_write(conn);
979  unlock_out(conn);
980  }
981 
982  /* Since we normally select for reading, we must
983  * try to read here. Otherwise, if the caller loops
984  * around conn_wait without making conn_read* calls
985  * in between, we will keep polling this same data. */
986  if (ret & POLLIN) {
987  lock_in(conn);
988  unlocked_read(conn);
989  unlock_in(conn);
990  }
991 
992  return 0;
993 }
void error(int err, const char *fmt,...)
Definition: log.c:648
int read_eof
Definition: conn.c:136
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
#define POLLNVAL
Definition: gwpoll.h:98
int io_error
Definition: conn.c:137
static void lock_out(Connection *conn)
Definition: conn.c:197
#define POLLIN
Definition: gwpoll.h:91
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
int fd
Definition: conn.c:119
#define POLLERR
Definition: gwpoll.h:96
int gwthread_pollfd(int fd, int events, double timeout)
static void lock_in(Connection *conn)
Definition: conn.c:172
static long unlocked_write(Connection *conn)
Definition: conn.c:235
#define unlock_out(conn)
Definition: conn.c:169
#define POLLHUP
Definition: gwpoll.h:97
#define POLLOUT
Definition: gwpoll.h:93

◆ conn_wrap_fd()

Connection* conn_wrap_fd ( int  fd,
int  ssl 
)

Definition at line 566 of file conn.c.

References Connection::callback, Connection::callback_data, Connection::callback_data_destroyer, Connection::claimed, conn_destroy(), Connection::connected, DEFAULT_OUTPUT_BUFFERING, error(), Connection::fd, Connection::inbuf, Connection::inbufpos, Connection::inlock, Connection::io_error, Connection::listening_pollin, Connection::listening_pollout, mutex_create, octstr_create, Connection::outbuf, Connection::outbufpos, Connection::outlock, Connection::output_buffering, Connection::read_eof, Connection::registered, socket_set_blocking(), and ssl.

Referenced by accept_thread(), boxc_create(), cgw_listener(), conn_open_tcp_nb_with_port(), conn_open_tcp_with_port(), emi2_listener(), fake_listener(), server_thread(), smpp_emu(), and start_wapbox().

567 {
568  Connection *conn;
569 
570  if (socket_set_blocking(fd, 0) < 0)
571  return NULL;
572 
573  conn = gw_malloc(sizeof(*conn));
574  conn->inlock = mutex_create();
575  conn->outlock = mutex_create();
576  conn->claimed = 0;
577 
578  conn->outbuf = octstr_create("");
579  conn->outbufpos = 0;
580  conn->inbuf = octstr_create("");
581  conn->inbufpos = 0;
582 
583  conn->fd = fd;
584  conn->connected = yes;
585  conn->read_eof = 0;
586  conn->io_error = 0;
588 
589  conn->registered = NULL;
590  conn->callback = NULL;
591  conn->callback_data = NULL;
592  conn->callback_data_destroyer = NULL;
593  conn->listening_pollin = 0;
594  conn->listening_pollout = 0;
595 #ifdef HAVE_LIBSSL
596  /*
597  * do all the SSL magic for this connection
598  */
599  if (ssl) {
600  conn->ssl = SSL_new(global_server_ssl_context);
601  conn->peer_certificate = NULL;
602 
603  /* SSL_set_fd can fail, so check it */
604  if (SSL_set_fd(conn->ssl, conn->fd) == 0) {
605  /* SSL_set_fd failed, log error and return NULL */
606  error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
607  conn_destroy(conn);
608  return NULL;
609  }
610  /* SSL_set_verify(conn->ssl, 0, NULL); */
611 
612  /* set read/write BIO layer to non-blocking mode */
613  BIO_set_nbio(SSL_get_rbio(conn->ssl), 1);
614  BIO_set_nbio(SSL_get_wbio(conn->ssl), 1);
615 
616  /* set accept state , SSL-Handshake will be handled transparent while SSL_[read|write] */
617  SSL_set_accept_state(conn->ssl);
618  } else {
619  conn->ssl = NULL;
620  conn->peer_certificate = NULL;
621  }
622 #endif /* HAVE_LIBSSL */
623 
624  return conn;
625 }
int listening_pollout
Definition: conn.c:148
void error(int err, const char *fmt,...)
Definition: log.c:648
int socket_set_blocking(int fd, int blocking)
Definition: socket.c:368
conn_callback_t * callback
Definition: conn.c:142
int ssl
Mutex * outlock
Definition: conn.c:112
FDSet * registered
Definition: conn.c:141
unsigned int output_buffering
Definition: conn.c:130
int read_eof
Definition: conn.c:136
#define mutex_create()
Definition: thread.h:96
int listening_pollin
Definition: conn.c:146
long outbufpos
Definition: conn.c:126
void * callback_data
Definition: conn.c:143
Octstr * outbuf
Definition: conn.c:125
int io_error
Definition: conn.c:137
volatile sig_atomic_t claimed
Definition: conn.c:113
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:144
#define DEFAULT_OUTPUT_BUFFERING
Definition: conn.c:103
void conn_destroy(Connection *conn)
Definition: conn.c:627
int fd
Definition: conn.c:119
#define octstr_create(cstr)
Definition: octstr.h:125
Mutex * inlock
Definition: conn.c:111
enum Connection::@56 connected
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ conn_write()

int conn_write ( Connection conn,
Octstr data 
)

Definition at line 1051 of file conn.c.

References lock_out(), octstr_append(), Connection::outbuf, unlock_out, and unlocked_try_write().

Referenced by cgwop_send(), emimsg_send(), handle_pdu(), http_send_reply(), main(), send_enquire_link(), send_gnack(), send_logoff(), send_pdu(), send_request(), send_smpp_thread(), send_unbind(), smpp_emu_handle_pdu(), smpp_emu_writer(), sms_to_client(), and smsc_emu_submit_ack().

1052 {
1053  int ret;
1054 
1055  lock_out(conn);
1056  octstr_append(conn->outbuf, data);
1057  ret = unlocked_try_write(conn);
1058  unlock_out(conn);
1059 
1060  return ret;
1061 }
static int unlocked_try_write(Connection *conn)
Definition: conn.c:289
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
Octstr * outbuf
Definition: conn.c:125
static void lock_out(Connection *conn)
Definition: conn.c:197
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_write_data()

int conn_write_data ( Connection conn,
unsigned char *  data,
long  length 
)

Definition at line 1063 of file conn.c.

References lock_out(), octstr_append_data(), Connection::outbuf, unlock_out, and unlocked_try_write().

1064 {
1065  int ret;
1066 
1067  lock_out(conn);
1068  octstr_append_data(conn->outbuf, data, length);
1069  ret = unlocked_try_write(conn);
1070  unlock_out(conn);
1071 
1072  return ret;
1073 }
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1497
static int unlocked_try_write(Connection *conn)
Definition: conn.c:289
Octstr * outbuf
Definition: conn.c:125
static void lock_out(Connection *conn)
Definition: conn.c:197
#define unlock_out(conn)
Definition: conn.c:169

◆ conn_write_withlen()

int conn_write_withlen ( Connection conn,
Octstr data 
)

Definition at line 1075 of file conn.c.

References encode_network_long(), lock_out(), octstr_append(), octstr_append_data(), octstr_len(), Connection::outbuf, unlock_out, and unlocked_try_write().

Referenced by deliver_to_bearerbox_real(), send_msg(), send_pdu(), smsbox_thread(), and write_to_bearerbox_real().

1076 {
1077  int ret;
1078  unsigned char lengthbuf[4];
1079 
1080  encode_network_long(lengthbuf, octstr_len(data));
1081  lock_out(conn);
1082  octstr_append_data(conn->outbuf, lengthbuf, 4);
1083  octstr_append(conn->outbuf, data);
1084  ret = unlocked_try_write(conn);
1085  unlock_out(conn);
1086 
1087  return ret;
1088 }
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1497
static int unlocked_try_write(Connection *conn)
Definition: conn.c:289
void encode_network_long(unsigned char *data, unsigned long value)
Definition: utils.c:940
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1504
Octstr * outbuf
Definition: conn.c:125
static void lock_out(Connection *conn)
Definition: conn.c:197
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
#define unlock_out(conn)
Definition: conn.c:169

◆ lock_in()

static void lock_in ( Connection conn)
inlinestatic

Definition at line 172 of file conn.c.

References Connection::claimed, Connection::claiming_thread, gw_assert(), gwthread_self(), Connection::inlock, and mutex_lock.

Referenced by conn_eof(), conn_error(), conn_inbuf_len(), conn_read_everything(), conn_read_fixed(), conn_read_line(), conn_read_packet(), conn_read_withlen(), conn_register_real(), conn_unregister(), conn_wait(), and poll_callback().

173 {
174  gw_assert(conn != NULL);
175 
176  if (conn->claimed)
178  else
179  mutex_lock(conn->inlock);
180 }
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
long claiming_thread
Definition: conn.c:115
volatile sig_atomic_t claimed
Definition: conn.c:113
Mutex * inlock
Definition: conn.c:111
#define mutex_lock(m)
Definition: thread.h:130

◆ lock_out()

static void lock_out ( Connection conn)
inlinestatic

Definition at line 197 of file conn.c.

References Connection::claimed, Connection::claiming_thread, gw_assert(), gwthread_self(), mutex_lock, and Connection::outlock.

Referenced by conn_error(), conn_flush(), conn_outbuf_len(), conn_register_real(), conn_set_output_buffering(), conn_unregister(), conn_wait(), conn_write(), conn_write_data(), conn_write_withlen(), and poll_callback().

198 {
199  gw_assert(conn != NULL);
200 
201  if (conn->claimed)
203  else
204  mutex_lock(conn->outlock);
205 }
long gwthread_self(void)
gw_assert(wtls_machine->packet_to_send !=NULL)
Mutex * outlock
Definition: conn.c:112
long claiming_thread
Definition: conn.c:115
volatile sig_atomic_t claimed
Definition: conn.c:113
#define mutex_lock(m)
Definition: thread.h:130

◆ poll_callback()

static void poll_callback ( int  fd,
int  revents,
void *  data 
)
static

Definition at line 738 of file conn.c.

References Connection::callback, Connection::callback_data, Connection::connected, error(), Connection::fd, Connection::io_error, Connection::listening_pollin, Connection::listening_pollout, lock_in(), lock_out(), POLLERR, POLLHUP, POLLIN, POLLOUT, unlock_in, unlock_out, unlocked_outbuf_len(), unlocked_read(), unlocked_register_pollin(), unlocked_register_pollout(), and unlocked_write().

Referenced by conn_register_real().

739 {
740  Connection *conn;
741  int do_callback = 0;
742 
743  conn = data;
744 
745  if (conn == NULL) {
746  error(0, "poll_callback called with NULL connection.");
747  return;
748  }
749 
750  if (conn->fd != fd) {
751  error(0, "poll_callback called on wrong connection.");
752  return;
753  }
754 
755  /* Get result of nonblocking connect, before any reads and writes
756  * we must check result (it must be handled in initial callback) */
757  if (conn->connected == no) {
758  if (conn->callback)
759  conn->callback(conn, conn->callback_data);
760  return;
761  }
762 
763  /* If got POLLERR or POLHUP, then unregister the descriptor from the
764  * fdset and set the error condition variable to let the upper layer
765  * close and destroy the connection. */
766  if (revents & (POLLERR|POLLHUP)) {
767  lock_out(conn);
768  lock_in(conn);
769  if (conn->listening_pollin)
770  unlocked_register_pollin(conn, 0);
771  if (conn->listening_pollout)
772  unlocked_register_pollout(conn, 0);
773  conn->io_error = 1;
774  unlock_in(conn);
775  unlock_out(conn);
776  do_callback = 1;
777  }
778 
779  /* If unlocked_write manages to write all pending data, it will
780  * tell the fdset to stop listening for POLLOUT. */
781  if (revents & POLLOUT) {
782  lock_out(conn);
783  unlocked_write(conn);
784  if (unlocked_outbuf_len(conn) == 0)
785  do_callback = 1;
786  unlock_out(conn);
787  }
788 
789  /* We read only in unlocked_read in we received POLLIN, cause the
790  * descriptor is already broken and of no use anymore. */
791  if (revents & POLLIN) {
792  lock_in(conn);
793  unlocked_read(conn);
794  unlock_in(conn);
795  do_callback = 1;
796  }
797 
798  if (do_callback && conn->callback)
799  conn->callback(conn, conn->callback_data);
800 }
int listening_pollout
Definition: conn.c:148
void error(int err, const char *fmt,...)
Definition: log.c:648
conn_callback_t * callback
Definition: conn.c:142
static void unlocked_register_pollin(Connection *conn, int onoff)
Definition: conn.c:377
static void unlocked_register_pollout(Connection *conn, int onoff)
Definition: conn.c:397
int listening_pollin
Definition: conn.c:146
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
void * callback_data
Definition: conn.c:143
int io_error
Definition: conn.c:137
static void lock_out(Connection *conn)
Definition: conn.c:197
#define POLLIN
Definition: gwpoll.h:91
static void unlocked_read(Connection *conn)
Definition: conn.c:310
#define unlock_in(conn)
Definition: conn.c:168
int fd
Definition: conn.c:119
#define POLLERR
Definition: gwpoll.h:96
enum Connection::@56 connected
static void lock_in(Connection *conn)
Definition: conn.c:172
static long unlocked_write(Connection *conn)
Definition: conn.c:235
#define unlock_out(conn)
Definition: conn.c:169
#define POLLHUP
Definition: gwpoll.h:97
#define POLLOUT
Definition: gwpoll.h:93

◆ unlock_in_real()

static void unlock_in_real ( Connection conn,
char *  file,
int  line,
const char *  func 
)
inlinestatic

Definition at line 183 of file conn.c.

References Connection::claimed, file, gw_assert(), Connection::inlock, mutex_unlock, and panic.

184 {
185  int ret;
186  gw_assert(conn != NULL);
187 
188  if (!conn->claimed && (ret = mutex_unlock(conn->inlock)) != 0) {
189  panic(0, "%s:%ld: %s: Mutex unlock failed. "
190  "(Called from %s:%ld:%s.)",
191  __FILE__, (long) __LINE__, __func__,
192  file, (long) line, func);
193  }
194 }
gw_assert(wtls_machine->packet_to_send !=NULL)
#define mutex_unlock(m)
Definition: thread.h:136
volatile sig_atomic_t claimed
Definition: conn.c:113
FILE * file
Definition: log.c:169
Mutex * inlock
Definition: conn.c:111
#define panic
Definition: log.h:87

◆ unlock_out_real()

static void unlock_out_real ( Connection conn,
char *  file,
int  line,
const char *  func 
)
inlinestatic

Definition at line 208 of file conn.c.

References Connection::claimed, file, gw_assert(), mutex_unlock, Connection::outlock, and panic.

209 {
210  int ret;
211  gw_assert(conn != NULL);
212 
213  if (!conn->claimed && (ret = mutex_unlock(conn->outlock)) != 0) {
214  panic(0, "%s:%ld: %s: Mutex unlock failed. "
215  "(Called from %s:%ld:%s.)",
216  __FILE__, (long) __LINE__, __func__,
217  file, (long) line, func);
218  }
219 }
gw_assert(wtls_machine->packet_to_send !=NULL)
Mutex * outlock
Definition: conn.c:112
#define mutex_unlock(m)
Definition: thread.h:136
volatile sig_atomic_t claimed
Definition: conn.c:113
FILE * file
Definition: log.c:169
#define panic
Definition: log.h:87

◆ unlocked_get()

static Octstr* unlocked_get ( Connection conn,
long  length 
)
static

Definition at line 361 of file conn.c.

References gw_assert(), Connection::inbuf, Connection::inbufpos, octstr_copy, and unlocked_inbuf_len().

Referenced by conn_read_everything(), conn_read_fixed(), conn_read_line(), conn_read_packet(), and conn_read_withlen().

362 {
363  Octstr *result = NULL;
364 
365  gw_assert(unlocked_inbuf_len(conn) >= length);
366  result = octstr_copy(conn->inbuf, conn->inbufpos, length);
367  conn->inbufpos += length;
368 
369  return result;
370 }
gw_assert(wtls_machine->packet_to_send !=NULL)
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:228
Definition: octstr.c:118
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ unlocked_inbuf_len()

static long unlocked_inbuf_len ( Connection conn)
inlinestatic

Definition at line 228 of file conn.c.

References Connection::inbuf, Connection::inbufpos, and octstr_len().

Referenced by conn_inbuf_len(), conn_read_everything(), conn_read_fixed(), conn_read_withlen(), and unlocked_get().

229 {
230  return octstr_len(conn->inbuf) - conn->inbufpos;
231 }
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ unlocked_outbuf_len()

static long unlocked_outbuf_len ( Connection conn)
inlinestatic

Definition at line 222 of file conn.c.

References octstr_len(), Connection::outbuf, and Connection::outbufpos.

Referenced by conn_flush(), conn_outbuf_len(), conn_register_real(), conn_wait(), poll_callback(), unlocked_try_write(), and unlocked_write().

223 {
224  return octstr_len(conn->outbuf) - conn->outbufpos;
225 }
long outbufpos
Definition: conn.c:126
Octstr * outbuf
Definition: conn.c:125
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342

◆ unlocked_read()

static void unlocked_read ( Connection conn)
static

Definition at line 310 of file conn.c.

References error(), Connection::fd, Connection::inbuf, Connection::inbufpos, Connection::io_error, octstr_append_data(), octstr_delete(), Connection::read_eof, Connection::registered, and unlocked_register_pollin().

Referenced by conn_read_everything(), conn_read_fixed(), conn_read_line(), conn_read_packet(), conn_read_withlen(), conn_wait(), and poll_callback().

311 {
312  unsigned char buf[4096];
313  long len = 0;
314 
315  if (conn->inbufpos > 0) {
316  octstr_delete(conn->inbuf, 0, conn->inbufpos);
317  conn->inbufpos = 0;
318  }
319 
320 #ifdef HAVE_LIBSSL
321  if (conn->ssl != NULL) {
322  /* We should empty out all data in the SSL read buffer.
323  * If we don't, then the next poll() on the file descriptor will *not* behave as expected.
324  */
325  do {
326  octstr_append_data(conn->inbuf, buf, len);
327  len = SSL_read(conn->ssl, buf, sizeof(buf));
328  } while (len > 0 && SSL_pending(conn->ssl) > 0);
329  } else
330 #endif /* HAVE_LIBSSL */
331  len = read(conn->fd, buf, sizeof(buf));
332 
333  if (len < 0) {
334  if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
335  return;
336 #ifdef HAVE_LIBSSL
337  if (conn->ssl) {
338  int SSL_error = SSL_get_error(conn->ssl, len);
339  if (SSL_error == SSL_ERROR_WANT_WRITE || SSL_error == SSL_ERROR_WANT_READ)
340  return; /* no error */
341  error(errno, "SSL read failed: OpenSSL error %d: %s",
342  SSL_error, ERR_error_string(SSL_error, NULL));
343  }
344  else
345 #endif /* HAVE_LIBSSL */
346  error(errno, "Error reading from fd %d:", conn->fd);
347  conn->io_error = 1;
348  if (conn->registered)
349  unlocked_register_pollin(conn, 0);
350  return;
351  } else if (len == 0) {
352  conn->read_eof = 1;
353  if (conn->registered)
354  unlocked_register_pollin(conn, 0);
355  } else {
356  octstr_append_data(conn->inbuf, buf, len);
357  }
358 }
void error(int err, const char *fmt,...)
Definition: log.c:648
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1497
FDSet * registered
Definition: conn.c:141
int read_eof
Definition: conn.c:136
static void unlocked_register_pollin(Connection *conn, int onoff)
Definition: conn.c:377
int io_error
Definition: conn.c:137
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
int fd
Definition: conn.c:119
Octstr * inbuf
Definition: conn.c:133
long inbufpos
Definition: conn.c:134

◆ unlocked_register_pollin()

static void unlocked_register_pollin ( Connection conn,
int  onoff 
)
static

Definition at line 377 of file conn.c.

References Connection::fd, fdset_listen(), gw_assert(), Connection::listening_pollin, POLLIN, and Connection::registered.

Referenced by poll_callback(), and unlocked_read().

378 {
379  gw_assert(conn->registered);
380 
381  if (onoff == 1 && !conn->listening_pollin) {
382  /* Turn it on */
383  conn->listening_pollin = 1;
384  fdset_listen(conn->registered, conn->fd, POLLIN, POLLIN);
385  } else if (onoff == 0 && conn->listening_pollin) {
386  /* Turn it off */
387  conn->listening_pollin = 0;
388  fdset_listen(conn->registered, conn->fd, POLLIN, 0);
389  }
390 }
void fdset_listen(FDSet *set, int fd, int mask, int events)
Definition: fdset.c:470
gw_assert(wtls_machine->packet_to_send !=NULL)
FDSet * registered
Definition: conn.c:141
int listening_pollin
Definition: conn.c:146
#define POLLIN
Definition: gwpoll.h:91
int fd
Definition: conn.c:119

◆ unlocked_register_pollout()

static void unlocked_register_pollout ( Connection conn,
int  onoff 
)
static

Definition at line 397 of file conn.c.

References Connection::fd, fdset_listen(), gw_assert(), Connection::listening_pollout, POLLOUT, and Connection::registered.

Referenced by poll_callback(), and unlocked_write().

398 {
399  gw_assert(conn->registered);
400 
401  if (onoff == 1 && !conn->listening_pollout) {
402  /* Turn it on */
403  conn->listening_pollout = 1;
404  fdset_listen(conn->registered, conn->fd, POLLOUT, POLLOUT);
405  } else if (onoff == 0 && conn->listening_pollout) {
406  /* Turn it off */
407  conn->listening_pollout = 0;
408  fdset_listen(conn->registered, conn->fd, POLLOUT, 0);
409  }
410 }
int listening_pollout
Definition: conn.c:148
void fdset_listen(FDSet *set, int fd, int mask, int events)
Definition: fdset.c:470
gw_assert(wtls_machine->packet_to_send !=NULL)
FDSet * registered
Definition: conn.c:141
int fd
Definition: conn.c:119
#define POLLOUT
Definition: gwpoll.h:93

◆ unlocked_try_write()

static int unlocked_try_write ( Connection conn)
static

Definition at line 289 of file conn.c.

References Connection::output_buffering, unlocked_outbuf_len(), and unlocked_write().

Referenced by conn_destroy(), conn_set_output_buffering(), conn_write(), conn_write_data(), and conn_write_withlen().

290 {
291  long len;
292 
293  len = unlocked_outbuf_len(conn);
294  if (len == 0)
295  return 0;
296 
297  if (len < (long) conn->output_buffering)
298  return 1;
299 
300  if (unlocked_write(conn) < 0)
301  return -1;
302 
303  if (unlocked_outbuf_len(conn) > 0)
304  return 1;
305 
306  return 0;
307 }
unsigned int output_buffering
Definition: conn.c:130
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
static long unlocked_write(Connection *conn)
Definition: conn.c:235

◆ unlocked_write()

static long unlocked_write ( Connection conn)
static

Definition at line 235 of file conn.c.

References error(), Connection::fd, Connection::io_error, octstr_delete(), octstr_get_cstr, octstr_len(), octstr_write_data(), Connection::outbuf, Connection::outbufpos, Connection::registered, unlocked_outbuf_len(), and unlocked_register_pollout().

Referenced by conn_flush(), conn_wait(), poll_callback(), and unlocked_try_write().

236 {
237  long ret = 0;
238 
239 #ifdef HAVE_LIBSSL
240  if (conn->ssl != NULL) {
241  if (octstr_len(conn->outbuf) - conn->outbufpos > 0)
242  ret = SSL_write(conn->ssl,
243  octstr_get_cstr(conn->outbuf) + conn->outbufpos,
244  octstr_len(conn->outbuf) - conn->outbufpos);
245 
246  if (ret < 0) {
247  int SSL_error = SSL_get_error(conn->ssl, ret);
248 
249  if (SSL_error == SSL_ERROR_WANT_READ || SSL_error == SSL_ERROR_WANT_WRITE) {
250  ret = 0; /* no error */
251  } else {
252  error(errno, "SSL write failed: OpenSSL error %d: %s",
253  SSL_error, ERR_error_string(SSL_error, NULL));
254  if (SSL_error == SSL_ERROR_SSL) { /* trace library errors */
255  long err;
256  while ((err = ERR_get_error()) != 0)
257  error(0, "SSL %s", ERR_error_string(err, NULL));
258  }
259  return -1;
260  }
261  }
262  } else
263 #endif /* HAVE_LIBSSL */
264  ret = octstr_write_data(conn->outbuf, conn->fd, conn->outbufpos);
265 
266  if (ret < 0) {
267  conn->io_error = 1;
268  return -1;
269  }
270 
271  conn->outbufpos += ret;
272 
273  /* Heuristic: Discard the already-written data if it's more than
274  * half of the total. This should keep the buffer size small
275  * without wasting too many cycles on moving data around. */
276  if (conn->outbufpos > octstr_len(conn->outbuf) / 2) {
277  octstr_delete(conn->outbuf, 0, conn->outbufpos);
278  conn->outbufpos = 0;
279  }
280 
281  if (conn->registered)
283 
284  return ret;
285 }
void error(int err, const char *fmt,...)
Definition: log.c:648
FDSet * registered
Definition: conn.c:141
static void unlocked_register_pollout(Connection *conn, int onoff)
Definition: conn.c:397
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:222
long outbufpos
Definition: conn.c:126
Octstr * outbuf
Definition: conn.c:125
int io_error
Definition: conn.c:137
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1527
int fd
Definition: conn.c:119
long octstr_write_data(Octstr *ostr, int fd, long from)
Definition: octstr.c:1255
long octstr_len(const Octstr *ostr)
Definition: octstr.c:342
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.