Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
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

#define DEFAULT_OUTPUT_BUFFERING   0

Definition at line 101 of file conn.c.

Referenced by conn_wrap_fd().

#define SSL_CONN_TIMEOUT   30

Definition at line 102 of file conn.c.

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

Typedef Documentation

typedef unsigned long(* CRYPTO_CALLBACK_PTR) (void)

Definition at line 92 of file conn.c.

Function Documentation

void conn_claim ( Connection conn)

Definition at line 663 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().

664 {
665  gw_assert(conn != NULL);
666 
667  if (conn->claimed)
668  panic(0, "Connection is being claimed twice!");
669  conn->claimed = 1;
670 #ifndef NO_GWASSERT
671  conn->claiming_thread = gwthread_self();
672 #endif
673 }
long gwthread_self(void)
long claiming_thread
Definition: conn.c:113
volatile sig_atomic_t claimed
Definition: conn.c:111
gw_assert(wtls_machine->packet_to_send!=NULL)
#define panic
Definition: log.h:87
void conn_config_ssl ( CfgGroup grp)

Definition at line 1472 of file conn.c.

References info().

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

1473 {
1474  info(0, "SSL not supported, no SSL initialization done.");
1475 }
void info(int err, const char *fmt,...)
Definition: log.c:636
void conn_destroy ( Connection conn)

Definition at line 619 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().

620 {
621  int ret;
622 
623  if (conn == NULL)
624  return;
625 
626  /* No locking done here. conn_destroy should not be called
627  * if any thread might still be interested in the connection. */
628 
629  if (conn->registered) {
630  fdset_unregister(conn->registered, conn->fd);
631  /* call data destroyer if any */
632  if (conn->callback_data != NULL && conn->callback_data_destroyer != NULL)
634  }
635 
636  if (conn->fd >= 0) {
637  /* Try to flush any remaining data */
638  unlocked_try_write(conn);
639 
640 #ifdef HAVE_LIBSSL
641  if (conn->ssl != NULL) {
642  SSL_smart_shutdown(conn->ssl);
643  SSL_free(conn->ssl);
644  if (conn->peer_certificate != NULL)
645  X509_free(conn->peer_certificate);
646  }
647 #endif /* HAVE_LIBSSL */
648 
649  ret = close(conn->fd);
650  if (ret < 0)
651  error(errno, "conn_destroy: error on close");
652  conn->fd = -1;
653  }
654 
655  octstr_destroy(conn->outbuf);
656  octstr_destroy(conn->inbuf);
657  mutex_destroy(conn->inlock);
658  mutex_destroy(conn->outlock);
659 
660  gw_free(conn);
661 }
void error(int err, const char *fmt,...)
Definition: log.c:612
static int unlocked_try_write(Connection *conn)
Definition: conn.c:287
Mutex * outlock
Definition: conn.c:110
FDSet * registered
Definition: conn.c:139
void * callback_data
Definition: conn.c:141
Octstr * outbuf
Definition: conn.c:123
void fdset_unregister(FDSet *set, int fd)
Definition: fdset.c:510
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:142
int fd
Definition: conn.c:117
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:322
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
Mutex * inlock
Definition: conn.c:109
Octstr * inbuf
Definition: conn.c:131
int conn_error ( Connection conn)

Definition at line 708 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().

709 {
710  int err;
711 
712  lock_out(conn);
713  lock_in(conn);
714  err = conn->io_error;
715  unlock_in(conn);
716  unlock_out(conn);
717 
718  return err;
719 }
int io_error
Definition: conn.c:135
static void lock_out(Connection *conn)
Definition: conn.c:195
#define unlock_in(conn)
Definition: conn.c:166
static void lock_in(Connection *conn)
Definition: conn.c:170
#define unlock_out(conn)
Definition: conn.c:167
int conn_flush ( Connection conn)

Definition at line 987 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().

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

Definition at line 522 of file conn.c.

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

Referenced by handle_transaction().

523 {
524  int err;
525  socklen_t len;
526 
527  len = sizeof(err);
528  if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
529  return -1;
530  }
531 
532  if (err) {
533  return -1;
534  }
535 
536  conn->connected = yes;
537  return 0;
538 }
int fd
Definition: conn.c:117
enum Connection::@56 connected
int socklen_t
Definition: socket.h:73
int conn_get_id ( Connection conn)

Definition at line 1478 of file conn.c.

References Connection::fd.

Referenced by conn_pool_get().

1478  {
1479  if(conn == NULL)
1480  return 0;
1481  else
1482  return conn->fd;
1483 }
int fd
Definition: conn.c:117
long conn_inbuf_len ( Connection conn)

Definition at line 686 of file conn.c.

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

687 {
688  long len;
689 
690  lock_in(conn);
691  len = unlocked_inbuf_len(conn);
692  unlock_in(conn);
693 
694  return len;
695 }
#define unlock_in(conn)
Definition: conn.c:166
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:226
static void lock_in(Connection *conn)
Definition: conn.c:170
int conn_is_connected ( Connection conn)

Definition at line 517 of file conn.c.

References Connection::connected.

Referenced by write_request_thread().

518 {
519  return conn->connected == yes ? 0 : -1;
520 }
enum Connection::@56 connected
Connection* conn_open_tcp ( Octstr host,
int  port,
Octstr our_host 
)

Definition at line 488 of file conn.c.

References conn_open_tcp_with_port().

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

489 {
490  return conn_open_tcp_with_port(host, port, 0, our_host);
491 }
Definition: http.c:1998
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:540
Connection* conn_open_tcp_nb ( Octstr host,
int  port,
Octstr our_host 
)

Definition at line 493 of file conn.c.

References conn_open_tcp_nb_with_port().

Referenced by conn_pool_get().

494 {
495  return conn_open_tcp_nb_with_port(host, port, 0, our_host);
496 }
Definition: http.c:1998
Connection * conn_open_tcp_nb_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
Definition: conn.c:498
Connection* conn_open_tcp_nb_with_port ( Octstr host,
int  port,
int  our_port,
Octstr our_host 
)

Definition at line 498 of file conn.c.

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

Referenced by conn_open_tcp_nb().

500 {
501  int sockfd;
502  int done = -1;
503  Connection *c;
504 
506  our_port, our_host == NULL ?
507  NULL : octstr_get_cstr(our_host), &done);
508  if (sockfd < 0)
509  return NULL;
510  c = conn_wrap_fd(sockfd, 0);
511  if (done != 0) {
512  c->connected = no;
513  }
514  return c;
515 }
static long our_port
Definition: radius_acct.c:87
Definition: http.c:1998
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
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:558
Connection* conn_open_tcp_with_port ( Octstr host,
int  port,
int  our_port,
Octstr our_host 
)

Definition at line 540 of file conn.c.

References conn_wrap_fd(), octstr_get_cstr, 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().

542 {
543  int sockfd;
544 
546  our_port, our_host == NULL ?
547  NULL : octstr_get_cstr(our_host));
548  if (sockfd < 0)
549  return NULL;
550  return conn_wrap_fd(sockfd, 0);
551 }
static long our_port
Definition: radius_acct.c:87
Definition: http.c:1998
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
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:558
long conn_outbuf_len ( Connection conn)

Definition at line 675 of file conn.c.

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

Referenced by receive_request().

676 {
677  long len;
678 
679  lock_out(conn);
680  len = unlocked_outbuf_len(conn);
681  unlock_out(conn);
682 
683  return len;
684 }
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:220
static void lock_out(Connection *conn)
Definition: conn.c:195
#define unlock_out(conn)
Definition: conn.c:167
Octstr* conn_read_everything ( Connection conn)

Definition at line 1082 of file conn.c.

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

Referenced by read_body_until_eof().

1083 {
1084  Octstr *result = NULL;
1085 
1086  lock_in(conn);
1087  if (unlocked_inbuf_len(conn) == 0) {
1088  unlocked_read(conn);
1089  if (unlocked_inbuf_len(conn) == 0) {
1090  unlock_in(conn);
1091  return NULL;
1092  }
1093  }
1094 
1095  result = unlocked_get(conn, unlocked_inbuf_len(conn));
1096  gw_claim_area(result);
1097  unlock_in(conn);
1098 
1099  return result;
1100 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:353
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:226
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:170
Octstr* conn_read_fixed ( Connection conn,
long  length 
)

Definition at line 1102 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().

1103 {
1104  Octstr *result = NULL;
1105 
1106  if (length < 1)
1107  return NULL;
1108 
1109  /* See if the data is already available. If not, try a read(),
1110  * then see if we have enough data after that. If not, give up. */
1111  lock_in(conn);
1112  if (unlocked_inbuf_len(conn) < length) {
1113  unlocked_read(conn);
1114  if (unlocked_inbuf_len(conn) < length) {
1115  unlock_in(conn);
1116  return NULL;
1117  }
1118  }
1119  result = unlocked_get(conn, length);
1120  gw_claim_area(result);
1121  unlock_in(conn);
1122 
1123  return result;
1124 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:353
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:226
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:170
Octstr* conn_read_line ( Connection conn)

Definition at line 1126 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().

1127 {
1128  Octstr *result = NULL;
1129  long pos;
1130 
1131  lock_in(conn);
1132  /* 10 is the code for linefeed. We don't rely on \n because that
1133  * might be a different value on some (strange) systems, and
1134  * we are reading from a network connection. */
1135  pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
1136  if (pos < 0) {
1137  unlocked_read(conn);
1138  pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
1139  if (pos < 0) {
1140  unlock_in(conn);
1141  return NULL;
1142  }
1143  }
1144 
1145  result = unlocked_get(conn, pos - conn->inbufpos);
1146  gw_claim_area(result);
1147 
1148  /* Skip the LF, which we left in the buffer */
1149  conn->inbufpos++;
1150 
1151  /* If the line was terminated with CR LF, we have to remove
1152  * the CR from the result. */
1153  if (octstr_len(result) > 0 &&
1154  octstr_get_char(result, octstr_len(result) - 1) == 13)
1155  octstr_delete(result, octstr_len(result) - 1, 1);
1156 
1157  unlock_in(conn);
1158  return result;
1159 }
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Definition: octstr.c:1010
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:353
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:170
int octstr_get_char(const Octstr *ostr, long pos)
Definition: octstr.c:404
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
Octstr* conn_read_packet ( Connection conn,
int  startmark,
int  endmark 
)

Definition at line 1204 of file conn.c.

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

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

1205 {
1206  int startpos, endpos;
1207  Octstr *result = NULL;
1208  int try;
1209 
1210  lock_in(conn);
1211 
1212  for (try = 1; try <= 2; try++) {
1213  if (try > 1)
1214  unlocked_read(conn);
1215 
1216  /* Find startmark, and discard everything up to it */
1217  if (startmark >= 0) {
1218  startpos = octstr_search_char(conn->inbuf, startmark, conn->inbufpos);
1219  if (startpos < 0) {
1220  conn->inbufpos = octstr_len(conn->inbuf);
1221  continue;
1222  } else {
1223  conn->inbufpos = startpos;
1224  }
1225  } else {
1226  startpos = conn->inbufpos;
1227  }
1228 
1229  /* Find first endmark after startmark */
1230  endpos = octstr_search_char(conn->inbuf, endmark, conn->inbufpos);
1231  if (endpos < 0)
1232  continue;
1233 
1234  result = unlocked_get(conn, endpos - startpos + 1);
1235  gw_claim_area(result);
1236  break;
1237  }
1238 
1239  unlock_in(conn);
1240  return result;
1241 }
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:1010
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:353
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:170
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
Octstr* conn_read_withlen ( Connection conn)

Definition at line 1161 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().

1162 {
1163  Octstr *result = NULL;
1164  unsigned char lengthbuf[4];
1165  long length = 0; /* for compiler please */
1166  int try, retry;
1167 
1168  lock_in(conn);
1169 
1170  for (try = 1; try <= 2; try++) {
1171  if (try > 1)
1172  unlocked_read(conn);
1173 
1174  do {
1175  retry = 0;
1176  /* First get the length. */
1177  if (unlocked_inbuf_len(conn) < 4)
1178  continue;
1179 
1180  octstr_get_many_chars(lengthbuf, conn->inbuf, conn->inbufpos, 4);
1181  length = decode_network_long(lengthbuf);
1182 
1183  if (length < 0) {
1184  warning(0, "conn_read_withlen: got negative length, skipping");
1185  conn->inbufpos += 4;
1186  retry = 1;
1187  }
1188  } while(retry == 1);
1189 
1190  /* Then get the data. */
1191  if (unlocked_inbuf_len(conn) - 4 < length)
1192  continue;
1193 
1194  conn->inbufpos += 4;
1195  result = unlocked_get(conn, length);
1196  gw_claim_area(result);
1197  break;
1198  }
1199 
1200  unlock_in(conn);
1201  return result;
1202 }
static Octstr * unlocked_get(Connection *conn, long length)
Definition: conn.c:353
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
void warning(int err, const char *fmt,...)
Definition: log.c:624
long decode_network_long(unsigned char *data)
Definition: utils.c:935
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:226
Definition: octstr.c:118
static void lock_in(Connection *conn)
Definition: conn.c:170
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
Definition: octstr.c:423
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
int conn_register_real ( Connection conn,
FDSet fdset,
conn_callback_t  callback,
void *  data,
conn_callback_data_destroyer_t data_destroyer 
)

Definition at line 794 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().

796 {
797  int events;
798  int result = 0;
799 
800  gw_assert(conn != NULL);
801 
802  if (conn->fd < 0)
803  return -1;
804 
805  /* We need both locks if we want to update the registration
806  * information. */
807  lock_out(conn);
808  lock_in(conn);
809 
810  if (conn->registered == fdset) {
811  /* Re-registering. Change only the callback info. */
812  conn->callback = callback;
813  /* call data destroyer if new data supplied */
814  if (conn->callback_data != NULL && conn->callback_data != data && conn->callback_data_destroyer != NULL)
816  conn->callback_data = data;
817  conn->callback_data_destroyer = data_destroyer;
818  result = 0;
819  } else if (conn->registered) {
820  /* Already registered to a different fdset. */
821  result = -1;
822  } else {
823  events = 0;
824  /* For nonconnected socket we must lesten both directions */
825  if (conn->connected == yes) {
826  if (conn->read_eof == 0 && conn->io_error == 0)
827  events |= POLLIN;
828  if (unlocked_outbuf_len(conn) > 0)
829  events |= POLLOUT;
830  } else {
831  events |= POLLIN | POLLOUT;
832  }
833 
834  conn->registered = fdset;
835  conn->callback = callback;
836  conn->callback_data = data;
837  conn->callback_data_destroyer = data_destroyer;
838  conn->listening_pollin = (events & POLLIN) != 0;
839  conn->listening_pollout = (events & POLLOUT) != 0;
840  fdset_register(fdset, conn->fd, events, poll_callback, conn);
841  result = 0;
842  }
843 
844  unlock_in(conn);
845  unlock_out(conn);
846 
847  return result;
848 }
int listening_pollout
Definition: conn.c:146
conn_callback_t * callback
Definition: conn.c:140
FDSet * registered
Definition: conn.c:139
int read_eof
Definition: conn.c:134
int listening_pollin
Definition: conn.c:144
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:220
void * callback_data
Definition: conn.c:141
int io_error
Definition: conn.c:135
static void lock_out(Connection *conn)
Definition: conn.c:195
conn_callback_data_destroyer_t * callback_data_destroyer
Definition: conn.c:142
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:166
int fd
Definition: conn.c:117
gw_assert(wtls_machine->packet_to_send!=NULL)
static void poll_callback(int fd, int revents, void *data)
Definition: conn.c:730
enum Connection::@56 connected
static void lock_in(Connection *conn)
Definition: conn.c:170
#define unlock_out(conn)
Definition: conn.c:167
#define POLLOUT
Definition: gwpoll.h:93
void conn_set_output_buffering ( Connection conn,
unsigned int  size 
)

Definition at line 721 of file conn.c.

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

722 {
723  lock_out(conn);
724  conn->output_buffering = size;
725  /* If the buffer size is smaller, we may have to write immediately. */
726  unlocked_try_write(conn);
727  unlock_out(conn);
728 }
int size
Definition: wsasm.c:84
static int unlocked_try_write(Connection *conn)
Definition: conn.c:287
unsigned int output_buffering
Definition: conn.c:128
static void lock_out(Connection *conn)
Definition: conn.c:195
#define unlock_out(conn)
Definition: conn.c:167
void conn_unregister ( Connection conn)

Definition at line 850 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().

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

Definition at line 896 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().

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

Definition at line 558 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, and socket_set_blocking().

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().

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

Definition at line 1043 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().

1044 {
1045  int ret;
1046 
1047  lock_out(conn);
1048  octstr_append(conn->outbuf, data);
1049  ret = unlocked_try_write(conn);
1050  unlock_out(conn);
1051 
1052  return ret;
1053 }
static int unlocked_try_write(Connection *conn)
Definition: conn.c:287
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:1502
Octstr * outbuf
Definition: conn.c:123
static void lock_out(Connection *conn)
Definition: conn.c:195
#define unlock_out(conn)
Definition: conn.c:167
int conn_write_data ( Connection conn,
unsigned char *  data,
long  length 
)

Definition at line 1055 of file conn.c.

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

1056 {
1057  int ret;
1058 
1059  lock_out(conn);
1060  octstr_append_data(conn->outbuf, data, length);
1061  ret = unlocked_try_write(conn);
1062  unlock_out(conn);
1063 
1064  return ret;
1065 }
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
static int unlocked_try_write(Connection *conn)
Definition: conn.c:287
Octstr * outbuf
Definition: conn.c:123
static void lock_out(Connection *conn)
Definition: conn.c:195
#define unlock_out(conn)
Definition: conn.c:167
int conn_write_withlen ( Connection conn,
Octstr data 
)

Definition at line 1067 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().

1068 {
1069  int ret;
1070  unsigned char lengthbuf[4];
1071 
1072  encode_network_long(lengthbuf, octstr_len(data));
1073  lock_out(conn);
1074  octstr_append_data(conn->outbuf, lengthbuf, 4);
1075  octstr_append(conn->outbuf, data);
1076  ret = unlocked_try_write(conn);
1077  unlock_out(conn);
1078 
1079  return ret;
1080 }
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
static int unlocked_try_write(Connection *conn)
Definition: conn.c:287
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:1502
Octstr * outbuf
Definition: conn.c:123
static void lock_out(Connection *conn)
Definition: conn.c:195
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
#define unlock_out(conn)
Definition: conn.c:167
static void lock_in ( Connection conn)
inlinestatic

Definition at line 170 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().

171 {
172  gw_assert(conn != NULL);
173 
174  if (conn->claimed)
176  else
177  mutex_lock(conn->inlock);
178 }
long gwthread_self(void)
long claiming_thread
Definition: conn.c:113
volatile sig_atomic_t claimed
Definition: conn.c:111
gw_assert(wtls_machine->packet_to_send!=NULL)
Mutex * inlock
Definition: conn.c:109
#define mutex_lock(m)
Definition: thread.h:130
static void lock_out ( Connection conn)
inlinestatic

Definition at line 195 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().

196 {
197  gw_assert(conn != NULL);
198 
199  if (conn->claimed)
201  else
202  mutex_lock(conn->outlock);
203 }
long gwthread_self(void)
Mutex * outlock
Definition: conn.c:110
long claiming_thread
Definition: conn.c:113
volatile sig_atomic_t claimed
Definition: conn.c:111
gw_assert(wtls_machine->packet_to_send!=NULL)
#define mutex_lock(m)
Definition: thread.h:130
static void poll_callback ( int  fd,
int  revents,
void *  data 
)
static

Definition at line 730 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().

731 {
732  Connection *conn;
733  int do_callback = 0;
734 
735  conn = data;
736 
737  if (conn == NULL) {
738  error(0, "poll_callback called with NULL connection.");
739  return;
740  }
741 
742  if (conn->fd != fd) {
743  error(0, "poll_callback called on wrong connection.");
744  return;
745  }
746 
747  /* Get result of nonblocking connect, before any reads and writes
748  * we must check result (it must be handled in initial callback) */
749  if (conn->connected == no) {
750  if (conn->callback)
751  conn->callback(conn, conn->callback_data);
752  return;
753  }
754 
755  /* If got POLLERR or POLHUP, then unregister the descriptor from the
756  * fdset and set the error condition variable to let the upper layer
757  * close and destroy the connection. */
758  if (revents & (POLLERR|POLLHUP)) {
759  lock_out(conn);
760  lock_in(conn);
761  if (conn->listening_pollin)
762  unlocked_register_pollin(conn, 0);
763  if (conn->listening_pollout)
764  unlocked_register_pollout(conn, 0);
765  conn->io_error = 1;
766  unlock_in(conn);
767  unlock_out(conn);
768  do_callback = 1;
769  }
770 
771  /* If unlocked_write manages to write all pending data, it will
772  * tell the fdset to stop listening for POLLOUT. */
773  if (revents & POLLOUT) {
774  lock_out(conn);
775  unlocked_write(conn);
776  if (unlocked_outbuf_len(conn) == 0)
777  do_callback = 1;
778  unlock_out(conn);
779  }
780 
781  /* We read only in unlocked_read in we received POLLIN, cause the
782  * descriptor is already broken and of no use anymore. */
783  if (revents & POLLIN) {
784  lock_in(conn);
785  unlocked_read(conn);
786  unlock_in(conn);
787  do_callback = 1;
788  }
789 
790  if (do_callback && conn->callback)
791  conn->callback(conn, conn->callback_data);
792 }
int listening_pollout
Definition: conn.c:146
void error(int err, const char *fmt,...)
Definition: log.c:612
conn_callback_t * callback
Definition: conn.c:140
static void unlocked_register_pollin(Connection *conn, int onoff)
Definition: conn.c:369
static void unlocked_register_pollout(Connection *conn, int onoff)
Definition: conn.c:389
int listening_pollin
Definition: conn.c:144
static long unlocked_outbuf_len(Connection *conn)
Definition: conn.c:220
void * callback_data
Definition: conn.c:141
int io_error
Definition: conn.c:135
static void lock_out(Connection *conn)
Definition: conn.c:195
#define POLLIN
Definition: gwpoll.h:91
static void unlocked_read(Connection *conn)
Definition: conn.c:308
#define unlock_in(conn)
Definition: conn.c:166
int fd
Definition: conn.c:117
#define POLLERR
Definition: gwpoll.h:96
enum Connection::@56 connected
static void lock_in(Connection *conn)
Definition: conn.c:170
static long unlocked_write(Connection *conn)
Definition: conn.c:233
#define unlock_out(conn)
Definition: conn.c:167
#define POLLHUP
Definition: gwpoll.h:97
#define POLLOUT
Definition: gwpoll.h:93
static void unlock_in_real ( Connection conn,
char *  file,
int  line,
const char *  func 
)
inlinestatic

Definition at line 181 of file conn.c.

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

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

Definition at line 206 of file conn.c.

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

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

Definition at line 353 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().

354 {
355  Octstr *result = NULL;
356 
357  gw_assert(unlocked_inbuf_len(conn) >= length);
358  result = octstr_copy(conn->inbuf, conn->inbufpos, length);
359  conn->inbufpos += length;
360 
361  return result;
362 }
#define octstr_copy(ostr, from, len)
Definition: octstr.h:178
gw_assert(wtls_machine->packet_to_send!=NULL)
static long unlocked_inbuf_len(Connection *conn)
Definition: conn.c:226
Definition: octstr.c:118
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
static long unlocked_inbuf_len ( Connection conn)
inlinestatic

Definition at line 226 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().

227 {
228  return octstr_len(conn->inbuf) - conn->inbufpos;
229 }
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
static long unlocked_outbuf_len ( Connection conn)
inlinestatic

Definition at line 220 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().

221 {
222  return octstr_len(conn->outbuf) - conn->outbufpos;
223 }
long outbufpos
Definition: conn.c:124
Octstr * outbuf
Definition: conn.c:123
long octstr_len(const Octstr *ostr)
Definition: octstr.c:340
static void unlocked_read ( Connection conn)
static

Definition at line 308 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().

309 {
310  unsigned char buf[4096];
311  long len;
312 
313  if (conn->inbufpos > 0) {
314  octstr_delete(conn->inbuf, 0, conn->inbufpos);
315  conn->inbufpos = 0;
316  }
317 
318 #ifdef HAVE_LIBSSL
319  if (conn->ssl != NULL) {
320  len = SSL_read(conn->ssl, buf, sizeof(buf));
321  } else
322 #endif /* HAVE_LIBSSL */
323  len = read(conn->fd, buf, sizeof(buf));
324 
325  if (len < 0) {
326  if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
327  return;
328 #ifdef HAVE_LIBSSL
329  if (conn->ssl) {
330  int SSL_error = SSL_get_error(conn->ssl, len);
331  if (SSL_error == SSL_ERROR_WANT_WRITE || SSL_error == SSL_ERROR_WANT_READ)
332  return; /* no error */
333  error(errno, "SSL read failed: OpenSSL error %d: %s",
334  SSL_error, ERR_error_string(SSL_error, NULL));
335  }
336  else
337 #endif /* HAVE_LIBSSL */
338  error(errno, "Error reading from fd %d:", conn->fd);
339  conn->io_error = 1;
340  if (conn->registered)
341  unlocked_register_pollin(conn, 0);
342  return;
343  } else if (len == 0) {
344  conn->read_eof = 1;
345  if (conn->registered)
346  unlocked_register_pollin(conn, 0);
347  } else {
348  octstr_append_data(conn->inbuf, buf, len);
349  }
350 }
void error(int err, const char *fmt,...)
Definition: log.c:612
void octstr_append_data(Octstr *ostr, const char *data, long len)
Definition: octstr.c:1495
FDSet * registered
Definition: conn.c:139
int read_eof
Definition: conn.c:134
static void unlocked_register_pollin(Connection *conn, int onoff)
Definition: conn.c:369
int io_error
Definition: conn.c:135
void octstr_delete(Octstr *ostr1, long pos, long len)
Definition: octstr.c:1525
int fd
Definition: conn.c:117
Octstr * inbuf
Definition: conn.c:131
long inbufpos
Definition: conn.c:132
static void unlocked_register_pollin ( Connection conn,
int  onoff 
)
static

Definition at line 369 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().

370 {
371  gw_assert(conn->registered);
372 
373  if (onoff == 1 && !conn->listening_pollin) {
374  /* Turn it on */
375  conn->listening_pollin = 1;
376  fdset_listen(conn->registered, conn->fd, POLLIN, POLLIN);
377  } else if (onoff == 0 && conn->listening_pollin) {
378  /* Turn it off */
379  conn->listening_pollin = 0;
380  fdset_listen(conn->registered, conn->fd, POLLIN, 0);
381  }
382 }
void fdset_listen(FDSet *set, int fd, int mask, int events)
Definition: fdset.c:470
FDSet * registered
Definition: conn.c:139
int listening_pollin
Definition: conn.c:144
#define POLLIN
Definition: gwpoll.h:91
int fd
Definition: conn.c:117
gw_assert(wtls_machine->packet_to_send!=NULL)
static void unlocked_register_pollout ( Connection conn,
int  onoff 
)
static

Definition at line 389 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().

390 {
391  gw_assert(conn->registered);
392 
393  if (onoff == 1 && !conn->listening_pollout) {
394  /* Turn it on */
395  conn->listening_pollout = 1;
396  fdset_listen(conn->registered, conn->fd, POLLOUT, POLLOUT);
397  } else if (onoff == 0 && conn->listening_pollout) {
398  /* Turn it off */
399  conn->listening_pollout = 0;
400  fdset_listen(conn->registered, conn->fd, POLLOUT, 0);
401  }
402 }
int listening_pollout
Definition: conn.c:146
void fdset_listen(FDSet *set, int fd, int mask, int events)
Definition: fdset.c:470
FDSet * registered
Definition: conn.c:139
int fd
Definition: conn.c:117
gw_assert(wtls_machine->packet_to_send!=NULL)
#define POLLOUT
Definition: gwpoll.h:93
static int unlocked_try_write ( Connection conn)
static

Definition at line 287 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().

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

Definition at line 233 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().

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