Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


tcptls.h File Reference

Generic support for tcp/tls servers in Asterisk. More...

#include "asterisk/netsock2.h"
#include "asterisk/utils.h"
#include <openssl/ssl.h>
#include <openssl/err.h>

Go to the source code of this file.

Data Structures

struct  ast_tcptls_session_args
 arguments for the accepting thread More...
 
struct  ast_tcptls_session_instance
 
struct  ast_tls_config
 

Macros

#define AST_CERTFILE   "asterisk.pem"
 
#define DO_SSL   /* comment in/out if you want to support ssl */
 
#define HOOK_T   ssize_t
 
#define LEN_T   size_t
 

Enumerations

enum  ast_ssl_flags {
  AST_SSL_VERIFY_CLIENT = (1 << 0), AST_SSL_DONT_VERIFY_SERVER = (1 << 1), AST_SSL_IGNORE_COMMON_NAME = (1 << 2), AST_SSL_SSLV2_CLIENT = (1 << 3),
  AST_SSL_SSLV3_CLIENT = (1 << 4), AST_SSL_TLSV1_CLIENT = (1 << 5)
}
 

Functions

int ast_ssl_setup (struct ast_tls_config *cfg)
 Set up an SSL server. More...
 
void ast_ssl_teardown (struct ast_tls_config *cfg)
 free resources used by an SSL server More...
 
struct
ast_tcptls_session_instance
ast_tcptls_client_create (struct ast_tcptls_session_args *desc)
 
struct
ast_tcptls_session_instance
ast_tcptls_client_start (struct ast_tcptls_session_instance *tcptls_session)
 attempts to connect and start tcptls session, on error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned. More...
 
void ast_tcptls_close_session_file (struct ast_tcptls_session_instance *tcptls_session)
 Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NULL and it's file descriptor will be set to -1 by this function. More...
 
HOOK_T ast_tcptls_server_read (struct ast_tcptls_session_instance *ser, void *buf, size_t count)
 
void * ast_tcptls_server_root (void *)
 
void ast_tcptls_server_start (struct ast_tcptls_session_args *desc)
 This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept(). More...
 
void ast_tcptls_server_stop (struct ast_tcptls_session_args *desc)
 Shutdown a running server if there is one. More...
 
HOOK_T ast_tcptls_server_write (struct ast_tcptls_session_instance *ser, const void *buf, size_t count)
 
void ast_tcptls_stream_set_exclusive_input (struct ast_tcptls_stream *stream, int exclusive_input)
 Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts. More...
 
void ast_tcptls_stream_set_timeout_disable (struct ast_tcptls_stream *stream)
 Disable the TCP/TLS stream timeout timer. More...
 
void ast_tcptls_stream_set_timeout_inactivity (struct ast_tcptls_stream *stream, int timeout)
 Set the TCP/TLS stream inactivity timeout timer. More...
 
void ast_tcptls_stream_set_timeout_sequence (struct ast_tcptls_stream *stream, struct timeval start, int timeout)
 Set the TCP/TLS stream I/O sequence timeout timer. More...
 
int ast_tls_read_conf (struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value)
 Used to parse conf files containing tls/ssl options. More...
 

Detailed Description

Generic support for tcp/tls servers in Asterisk.

Note
In order to have TLS/SSL support, we need the openssl libraries. Still we can decide whether or not to use them by commenting in or out the DO_SSL macro.

TLS/SSL support is basically implemented by reading from a config file (currently http.conf and sip.conf) the names of the certificate and cipher to use, and then run ssl_setup() to create an appropriate SSL_CTX (ssl_ctx) If we support multiple domains, presumably we need to read multiple certificates.

When we are requested to open a TLS socket, we run make_file_from_fd() on the socket, to do the necessary setup. At the moment the context's name is hardwired in the function, but we can certainly make it into an extra parameter to the function.

We declare most of ssl support variables unconditionally, because their number is small and this simplifies the code.

Note
The ssl-support variables (ssl_ctx, do_ssl, certfile, cipher) and their setup should be moved to a more central place, e.g. asterisk.conf and the source files that processes it. Similarly, ssl_setup() should be run earlier in the startup process so modules have it available.

Definition in file tcptls.h.

Macro Definition Documentation

#define AST_CERTFILE   "asterisk.pem"

SSL support

Definition at line 68 of file tcptls.h.

Referenced by __ast_http_load(), manager_set_defaults(), and reload_config().

#define DO_SSL   /* comment in/out if you want to support ssl */

Definition at line 55 of file tcptls.h.

#define HOOK_T   ssize_t

Definition at line 225 of file tcptls.h.

#define LEN_T   size_t

Definition at line 226 of file tcptls.h.

Enumeration Type Documentation

Enumerator
AST_SSL_VERIFY_CLIENT 

Verify certificate when acting as server

AST_SSL_DONT_VERIFY_SERVER 

Don't verify certificate when connecting to a server

AST_SSL_IGNORE_COMMON_NAME 

Don't compare "Common Name" against IP or hostname

AST_SSL_SSLV2_CLIENT 

Use SSLv2 for outgoing client connections

AST_SSL_SSLV3_CLIENT 

Use SSLv3 for outgoing client connections

AST_SSL_TLSV1_CLIENT 

Use TLSv1 for outgoing client connections

Definition at line 70 of file tcptls.h.

70  {
71  /*! Verify certificate when acting as server */
72  AST_SSL_VERIFY_CLIENT = (1 << 0),
73  /*! Don't verify certificate when connecting to a server */
74  AST_SSL_DONT_VERIFY_SERVER = (1 << 1),
75  /*! Don't compare "Common Name" against IP or hostname */
76  AST_SSL_IGNORE_COMMON_NAME = (1 << 2),
77  /*! Use SSLv2 for outgoing client connections */
78  AST_SSL_SSLV2_CLIENT = (1 << 3),
79  /*! Use SSLv3 for outgoing client connections */
80  AST_SSL_SSLV3_CLIENT = (1 << 4),
81  /*! Use TLSv1 for outgoing client connections */
82  AST_SSL_TLSV1_CLIENT = (1 << 5)
83 };

Function Documentation

int ast_ssl_setup ( struct ast_tls_config cfg)

Set up an SSL server.

Parameters
cfgConfiguration for the SSL server
Return values
1Success
0Failure

Definition at line 850 of file tcptls.c.

References __ssl_setup().

Referenced by __ast_http_load(), __init_manager(), and reload_config().

851 {
852  return __ssl_setup(cfg, 0);
853 }
static int __ssl_setup(struct ast_tls_config *cfg, int client)
Definition: tcptls.c:745
void ast_ssl_teardown ( struct ast_tls_config cfg)

free resources used by an SSL server

Note
This only needs to be called if ast_ssl_setup() was directly called first.
Parameters
cfgConfiguration for the SSL server

Definition at line 855 of file tcptls.c.

References ast_tls_config::ssl_ctx.

Referenced by sip_tcptls_client_args_destructor(), and unload_module().

856 {
857 #ifdef DO_SSL
858  if (cfg->ssl_ctx) {
859  SSL_CTX_free(cfg->ssl_ctx);
860  cfg->ssl_ctx = NULL;
861  }
862 #endif
863 }
SSL_CTX * ssl_ctx
Definition: tcptls.h:93
struct ast_tcptls_session_instance* ast_tcptls_client_create ( struct ast_tcptls_session_args desc)

Definition at line 902 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ast_bind(), ast_debug, ast_log(), ast_mutex_init, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), ast_str_create(), ast_tcptls_session_instance::client, desc, errno, ast_tcptls_session_instance::fd, ast_tcptls_session_args::local_address, ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_args::name, ast_tcptls_session_args::old_address, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::parent, ast_tcptls_session_args::remote_address, ast_tcptls_session_instance::remote_address, session_instance_destructor(), and ast_tcptls_session_args::worker_fn.

Referenced by app_exec(), and sip_prepare_socket().

903 {
904  int x = 1;
905  struct ast_tcptls_session_instance *tcptls_session = NULL;
906 
907  /* Do nothing if nothing has changed */
908  if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) {
909  ast_debug(1, "Nothing changed in %s\n", desc->name);
910  return NULL;
911  }
912 
913  /* If we return early, there is no connection */
915 
916  if (desc->accept_fd != -1)
917  close(desc->accept_fd);
918 
919  desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ?
920  AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP);
921  if (desc->accept_fd < 0) {
922  ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n",
923  desc->name, strerror(errno));
924  return NULL;
925  }
926 
927  /* if a local address was specified, bind to it so the connection will
928  originate from the desired address */
929  if (!ast_sockaddr_isnull(&desc->local_address)) {
930  setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
931  if (ast_bind(desc->accept_fd, &desc->local_address)) {
932  ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
933  desc->name,
935  strerror(errno));
936  goto error;
937  }
938  }
939 
940  if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor)))
941  goto error;
942 
943  ast_mutex_init(&tcptls_session->lock);
944  tcptls_session->overflow_buf = ast_str_create(128);
945  tcptls_session->client = 1;
946  tcptls_session->fd = desc->accept_fd;
947  tcptls_session->parent = desc;
948  tcptls_session->parent->worker_fn = NULL;
949  ast_sockaddr_copy(&tcptls_session->remote_address,
950  &desc->remote_address);
951 
952  /* Set current info */
954  return tcptls_session;
955 
956 error:
957  close(desc->accept_fd);
958  desc->accept_fd = -1;
959  if (tcptls_session)
960  ao2_ref(tcptls_session, -1);
961  return NULL;
962 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
struct ast_str * overflow_buf
Definition: tcptls.h:216
#define LOG_WARNING
Definition: logger.h:144
struct ast_tcptls_session_args * parent
Definition: tcptls.h:208
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:462
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_sockaddr remote_address
Definition: tcptls.h:126
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static const char desc[]
Definition: cdr_radius.c:85
#define LOG_ERROR
Definition: logger.h:155
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void *(* worker_fn)(void *)
Definition: tcptls.h:135
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static void session_instance_destructor(void *obj)
Definition: tcptls.c:541
int errno
struct ast_sockaddr old_address
Definition: tcptls.h:125
const char * name
Definition: tcptls.h:136
#define ast_mutex_init(pmutex)
Definition: lock.h:152
struct ast_sockaddr local_address
Definition: tcptls.h:124
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
struct ast_sockaddr remote_address
Definition: tcptls.h:207
struct ast_tcptls_session_instance* ast_tcptls_client_start ( struct ast_tcptls_session_instance tcptls_session)

attempts to connect and start tcptls session, on error the tcptls_session's ref count is decremented, fd and file are closed, and NULL is returned.

Definition at line 865 of file tcptls.c.

References __ssl_setup(), ast_tcptls_session_args::accept_fd, ao2_ref, ast_connect(), ast_log(), ast_sockaddr_stringify(), desc, ast_tls_config::enabled, errno, handle_tcptls_connection(), LOG_ERROR, ast_tcptls_session_args::name, ast_tcptls_session_instance::parent, ast_tcptls_session_args::remote_address, and ast_tcptls_session_args::tls_cfg.

Referenced by _sip_tcp_helper_thread(), and app_exec().

866 {
868  int flags;
869 
870  if (!(desc = tcptls_session->parent)) {
871  goto client_start_error;
872  }
873 
874  if (ast_connect(desc->accept_fd, &desc->remote_address)) {
875  ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n",
876  desc->name,
878  strerror(errno));
879  goto client_start_error;
880  }
881 
882  flags = fcntl(desc->accept_fd, F_GETFL);
883  fcntl(desc->accept_fd, F_SETFL, flags & ~O_NONBLOCK);
884 
885  if (desc->tls_cfg) {
886  desc->tls_cfg->enabled = 1;
887  __ssl_setup(desc->tls_cfg, 1);
888  }
889 
890  return handle_tcptls_connection(tcptls_session);
891 
892 client_start_error:
893  if (desc) {
894  close(desc->accept_fd);
895  desc->accept_fd = -1;
896  }
897  ao2_ref(tcptls_session, -1);
898  return NULL;
899 
900 }
struct ast_tcptls_session_args * parent
Definition: tcptls.h:208
static void * handle_tcptls_connection(void *data)
creates a FILE * from the fd passed by the accept thread. This operation is potentially expensive (ce...
Definition: tcptls.c:560
arguments for the accepting thread
Definition: tcptls.h:123
struct ast_sockaddr remote_address
Definition: tcptls.h:126
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static int __ssl_setup(struct ast_tls_config *cfg, int client)
Definition: tcptls.c:745
static const char desc[]
Definition: cdr_radius.c:85
#define LOG_ERROR
Definition: logger.h:155
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
const char * name
Definition: tcptls.h:136
struct ast_tls_config * tls_cfg
Definition: tcptls.h:128
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
Definition: netsock2.c:467
int enabled
Definition: tcptls.h:86
void ast_tcptls_close_session_file ( struct ast_tcptls_session_instance tcptls_session)

Closes a tcptls session instance's file and/or file descriptor. The tcptls_session will be set to NULL and it's file descriptor will be set to -1 by this function.

Definition at line 1033 of file tcptls.c.

References ast_log(), errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, and LOG_ERROR.

Referenced by _sip_tcp_helper_thread(), ast_http_send(), ast_tcptls_server_root(), handle_tcptls_connection(), httpd_helper_thread(), and sip_prepare_socket().

1034 {
1035  if (tcptls_session->f) {
1036  fflush(tcptls_session->f);
1037  if (fclose(tcptls_session->f)) {
1038  ast_log(LOG_ERROR, "fclose() failed: %s\n", strerror(errno));
1039  }
1040  tcptls_session->f = NULL;
1041  tcptls_session->fd = -1;
1042  } else if (tcptls_session->fd != -1) {
1043  /*
1044  * Issuing shutdown() is necessary here to avoid a race
1045  * condition where the last data written may not appear
1046  * in the TCP stream. See ASTERISK-23548
1047  */
1048  shutdown(tcptls_session->fd, SHUT_RDWR);
1049  if (close(tcptls_session->fd)) {
1050  ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
1051  }
1052  tcptls_session->fd = -1;
1053  } else {
1054  ast_log(LOG_ERROR, "ast_tcptls_close_session_file invoked on session instance without file or file descriptor\n");
1055  }
1056 }
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
HOOK_T ast_tcptls_server_read ( struct ast_tcptls_session_instance ser,
void *  buf,
size_t  count 
)

Definition at line 519 of file tcptls.c.

References ast_log(), errno, ast_tcptls_stream::fd, LOG_ERROR, ast_tcptls_session_instance::stream_cookie, and tcptls_stream_read().

Referenced by sip_tcptls_read().

520 {
521  if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
522  ast_log(LOG_ERROR, "TCP/TLS read called on invalid stream.\n");
523  errno = EIO;
524  return -1;
525  }
526 
527  return tcptls_stream_read(tcptls_session->stream_cookie, buf, count);
528 }
static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
Definition: tcptls.c:126
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void* ast_tcptls_server_root ( void *  )

Definition at line 693 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ao2_alloc, ao2_ref, ast_accept(), ast_log(), ast_mutex_init, ast_pthread_create_detached_background, ast_sockaddr_copy(), ast_str_create(), ast_tcptls_close_session_file(), ast_wait_for_input(), ast_tcptls_session_instance::client, desc, errno, ast_tcptls_session_instance::fd, handle_tcptls_connection(), ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, ast_tcptls_session_instance::overflow_buf, ast_tcptls_session_instance::parent, ast_tcptls_session_args::periodic_fn, ast_tcptls_session_args::poll_timeout, ast_tcptls_session_instance::remote_address, and session_instance_destructor().

694 {
695  struct ast_tcptls_session_args *desc = data;
696  int fd;
697  struct ast_sockaddr addr;
698  struct ast_tcptls_session_instance *tcptls_session;
699  pthread_t launched;
700 
701  for (;;) {
702  int i, flags;
703 
704  if (desc->periodic_fn)
705  desc->periodic_fn(desc);
706  i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout);
707  if (i <= 0)
708  continue;
709  fd = ast_accept(desc->accept_fd, &addr);
710  if (fd < 0) {
711  if ((errno != EAGAIN) && (errno != EINTR))
712  ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno));
713  continue;
714  }
715  tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor);
716  if (!tcptls_session) {
717  ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno));
718  if (close(fd)) {
719  ast_log(LOG_ERROR, "close() failed: %s\n", strerror(errno));
720  }
721  continue;
722  }
723 
724  ast_mutex_init(&tcptls_session->lock);
725  tcptls_session->overflow_buf = ast_str_create(128);
726 
727  flags = fcntl(fd, F_GETFL);
728  fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
729  tcptls_session->fd = fd;
730  tcptls_session->parent = desc;
731  ast_sockaddr_copy(&tcptls_session->remote_address, &addr);
732 
733  tcptls_session->client = 0;
734 
735  /* This thread is now the only place that controls the single ref to tcptls_session */
736  if (ast_pthread_create_detached_background(&launched, NULL, handle_tcptls_connection, tcptls_session)) {
737  ast_log(LOG_WARNING, "Unable to launch helper thread: %s\n", strerror(errno));
738  ast_tcptls_close_session_file(tcptls_session);
739  ao2_ref(tcptls_session, -1);
740  }
741  }
742  return NULL;
743 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
struct ast_str * overflow_buf
Definition: tcptls.h:216
#define LOG_WARNING
Definition: logger.h:144
struct ast_tcptls_session_args * parent
Definition: tcptls.h:208
static void * handle_tcptls_connection(void *data)
creates a FILE * from the fd passed by the accept thread. This operation is potentially expensive (ce...
Definition: tcptls.c:560
struct ast_str * ast_str_create(size_t init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:420
arguments for the accepting thread
Definition: tcptls.h:123
Socket address structure.
Definition: netsock2.h:63
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
int ast_accept(int sockfd, struct ast_sockaddr *addr)
Wrapper around accept(2) that uses struct ast_sockaddr.
Definition: netsock2.c:456
#define ao2_ref(o, delta)
Definition: astobj2.h:472
static const char desc[]
Definition: cdr_radius.c:85
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:430
static void session_instance_destructor(void *obj)
Definition: tcptls.c:541
int errno
void ast_tcptls_close_session_file(struct ast_tcptls_session_instance *tcptls_session)
Closes a tcptls session instance&#39;s file and/or file descriptor. The tcptls_session will be set to NUL...
Definition: tcptls.c:1033
int ast_wait_for_input(int fd, int ms)
Definition: utils.c:1255
#define ast_mutex_init(pmutex)
Definition: lock.h:152
void(* periodic_fn)(void *)
Definition: tcptls.h:134
struct ast_sockaddr remote_address
Definition: tcptls.h:207
void ast_tcptls_server_start ( struct ast_tcptls_session_args desc)

This is a generic (re)start routine for a TCP server, which does the socket/bind/listen and starts a thread for handling accept().

Version
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 964 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ast_tcptls_session_args::accept_fn, ast_bind(), ast_debug, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_is_ipv6(), ast_sockaddr_isnull(), ast_sockaddr_setnull(), ast_sockaddr_stringify(), errno, ast_tcptls_session_args::local_address, LOG_ERROR, ast_tcptls_session_args::master, ast_tcptls_session_args::name, and ast_tcptls_session_args::old_address.

Referenced by __ast_http_load(), __init_manager(), and reload_config().

965 {
966  int flags;
967  int x = 1;
968 
969  /* Do nothing if nothing has changed */
970  if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
971  ast_debug(1, "Nothing changed in %s\n", desc->name);
972  return;
973  }
974 
975  /* If we return early, there is no one listening */
977 
978  /* Shutdown a running server if there is one */
979  if (desc->master != AST_PTHREADT_NULL) {
980  pthread_cancel(desc->master);
981  pthread_kill(desc->master, SIGURG);
982  pthread_join(desc->master, NULL);
983  }
984 
985  if (desc->accept_fd != -1)
986  close(desc->accept_fd);
987 
988  /* If there's no new server, stop here */
989  if (ast_sockaddr_isnull(&desc->local_address)) {
990  ast_debug(2, "Server disabled: %s\n", desc->name);
991  return;
992  }
993 
994  desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ?
995  AF_INET6 : AF_INET, SOCK_STREAM, 0);
996  if (desc->accept_fd < 0) {
997  ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno));
998  return;
999  }
1000 
1001  setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
1002  if (ast_bind(desc->accept_fd, &desc->local_address)) {
1003  ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n",
1004  desc->name,
1006  strerror(errno));
1007  goto error;
1008  }
1009  if (listen(desc->accept_fd, 10)) {
1010  ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name);
1011  goto error;
1012  }
1013  flags = fcntl(desc->accept_fd, F_GETFL);
1014  fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK);
1015  if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) {
1016  ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n",
1017  desc->name,
1019  strerror(errno));
1020  goto error;
1021  }
1022 
1023  /* Set current info */
1025 
1026  return;
1027 
1028 error:
1029  close(desc->accept_fd);
1030  desc->accept_fd = -1;
1031 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:121
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:462
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
#define ast_pthread_create_background(a, b, c, d)
Definition: utils.h:426
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
#define LOG_ERROR
Definition: logger.h:155
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
struct ast_sockaddr old_address
Definition: tcptls.h:125
const char * name
Definition: tcptls.h:136
struct ast_sockaddr local_address
Definition: tcptls.h:124
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
void *(* accept_fn)(void *)
Definition: tcptls.h:133
void ast_tcptls_server_stop ( struct ast_tcptls_session_args desc)

Shutdown a running server if there is one.

Version
1.6.1 changed desc parameter to be of ast_tcptls_session_args type

Definition at line 1058 of file tcptls.c.

References ast_tcptls_session_args::accept_fd, ast_debug, AST_PTHREADT_NULL, ast_tcptls_session_args::master, and ast_tcptls_session_args::name.

Referenced by __ast_http_load(), __init_manager(), http_shutdown(), manager_shutdown(), and unload_module().

1059 {
1060  if (desc->master != AST_PTHREADT_NULL) {
1061  pthread_cancel(desc->master);
1062  pthread_kill(desc->master, SIGURG);
1063  pthread_join(desc->master, NULL);
1064  desc->master = AST_PTHREADT_NULL;
1065  }
1066  if (desc->accept_fd != -1)
1067  close(desc->accept_fd);
1068  desc->accept_fd = -1;
1069  ast_debug(2, "Stopped server :: %s\n", desc->name);
1070 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_PTHREADT_NULL
Definition: lock.h:65
const char * name
Definition: tcptls.h:136
HOOK_T ast_tcptls_server_write ( struct ast_tcptls_session_instance ser,
const void *  buf,
size_t  count 
)

Definition at line 530 of file tcptls.c.

References ast_log(), errno, ast_tcptls_stream::fd, LOG_ERROR, ast_tcptls_session_instance::stream_cookie, and tcptls_stream_write().

Referenced by _sip_tcp_helper_thread().

531 {
532  if (!tcptls_session->stream_cookie || tcptls_session->stream_cookie->fd == -1) {
533  ast_log(LOG_ERROR, "TCP/TLS write called on invalid stream.\n");
534  errno = EIO;
535  return -1;
536  }
537 
538  return tcptls_stream_write(tcptls_session->stream_cookie, buf, count);
539 }
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static HOOK_T tcptls_stream_write(void *cookie, const char *buf, LEN_T size)
Definition: tcptls.c:250
void ast_tcptls_stream_set_exclusive_input ( struct ast_tcptls_stream stream,
int  exclusive_input 
)

Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts.

Parameters
streamTCP/TLS stream control data.
exclusive_inputTRUE if stream can exclusively wait for fd input. Otherwise, the stream will not wait for fd input. It will wait while trying to send data.
Note
The stream timeouts still need to be set.
Returns
Nothing

Definition at line 107 of file tcptls.c.

References ast_assert, and ast_tcptls_stream::exclusive_input.

Referenced by _sip_tcp_helper_thread(), httpd_helper_thread(), and session_do().

108 {
109  ast_assert(stream != NULL);
110 
111  stream->exclusive_input = exclusive_input;
112 }
#define ast_assert(a)
Definition: utils.h:738
int exclusive_input
Definition: tcptls.c:81
void ast_tcptls_stream_set_timeout_disable ( struct ast_tcptls_stream stream)

Disable the TCP/TLS stream timeout timer.

Parameters
streamTCP/TLS stream control data.
Returns
Nothing

Definition at line 84 of file tcptls.c.

References ast_assert, and ast_tcptls_stream::timeout.

Referenced by _sip_tcp_helper_thread(), and session_do().

85 {
86  ast_assert(stream != NULL);
87 
88  stream->timeout = -1;
89 }
#define ast_assert(a)
Definition: utils.h:738
int timeout
Timeout in ms relative to struct ast_tcptls_stream.start to wait for an event on struct ast_tcptls_st...
Definition: tcptls.c:79
void ast_tcptls_stream_set_timeout_inactivity ( struct ast_tcptls_stream stream,
int  timeout 
)

Set the TCP/TLS stream inactivity timeout timer.

Parameters
streamTCP/TLS stream control data.
timeoutNumber of milliseconds to wait for data transfer with the peer.

This is basically how much time we are willing to spend in an I/O call before we declare the peer unresponsive.

Note
Setting timeout to -1 disables the timeout.
Setting this timeout replaces the I/O sequence timeout timer.
Returns
Nothing

Definition at line 91 of file tcptls.c.

References ast_assert, ast_tcptls_stream::start, and ast_tcptls_stream::timeout.

Referenced by httpd_helper_thread().

92 {
93  ast_assert(stream != NULL);
94 
95  stream->start.tv_sec = 0;
96  stream->timeout = timeout;
97 }
struct timeval start
Start time from when an I/O sequence must complete by struct ast_tcptls_stream.timeout.
Definition: tcptls.c:64
#define ast_assert(a)
Definition: utils.h:738
int timeout
Timeout in ms relative to struct ast_tcptls_stream.start to wait for an event on struct ast_tcptls_st...
Definition: tcptls.c:79
void ast_tcptls_stream_set_timeout_sequence ( struct ast_tcptls_stream stream,
struct timeval  start,
int  timeout 
)

Set the TCP/TLS stream I/O sequence timeout timer.

Parameters
streamTCP/TLS stream control data.
startTime the I/O sequence timer starts.
timeoutNumber of milliseconds from the start time before timeout.

This is how much time are we willing to allow the peer to complete an operation that can take several I/O calls. The main use is as an authentication timer with us.

Note
Setting timeout to -1 disables the timeout.
Setting this timeout replaces the inactivity timeout timer.
Returns
Nothing

Definition at line 99 of file tcptls.c.

References ast_assert, ast_tcptls_stream::start, and ast_tcptls_stream::timeout.

Referenced by _sip_tcp_helper_thread(), and session_do().

100 {
101  ast_assert(stream != NULL);
102 
103  stream->start = start;
104  stream->timeout = timeout;
105 }
struct timeval start
Start time from when an I/O sequence must complete by struct ast_tcptls_stream.timeout.
Definition: tcptls.c:64
#define ast_assert(a)
Definition: utils.h:738
int timeout
Timeout in ms relative to struct ast_tcptls_stream.start to wait for an event on struct ast_tcptls_st...
Definition: tcptls.c:79
int ast_tls_read_conf ( struct ast_tls_config tls_cfg,
struct ast_tcptls_session_args tls_desc,
const char *  varname,
const char *  value 
)

Used to parse conf files containing tls/ssl options.

Definition at line 1072 of file tcptls.c.

References ast_clear_flag, ast_free, ast_log(), ast_parse_arg(), ast_set2_flag, ast_set_flag, AST_SSL_DONT_VERIFY_SERVER, AST_SSL_SSLV2_CLIENT, AST_SSL_SSLV3_CLIENT, AST_SSL_TLSV1_CLIENT, AST_SSL_VERIFY_CLIENT, ast_strdup, ast_true(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tls_config::enabled, ast_tls_config::flags, ast_tcptls_session_args::local_address, LOG_WARNING, PARSE_ADDR, and ast_tls_config::pvtfile.

Referenced by __ast_http_load(), __init_manager(), and reload_config().

1073 {
1074  if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) {
1075  tls_cfg->enabled = ast_true(value) ? 1 : 0;
1076  } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) {
1077  ast_free(tls_cfg->certfile);
1078  tls_cfg->certfile = ast_strdup(value);
1079  } else if (!strcasecmp(varname, "tlsprivatekey") || !strcasecmp(varname, "sslprivatekey")) {
1080  ast_free(tls_cfg->pvtfile);
1081  tls_cfg->pvtfile = ast_strdup(value);
1082  } else if (!strcasecmp(varname, "tlscipher") || !strcasecmp(varname, "sslcipher")) {
1083  ast_free(tls_cfg->cipher);
1084  tls_cfg->cipher = ast_strdup(value);
1085  } else if (!strcasecmp(varname, "tlscafile")) {
1086  ast_free(tls_cfg->cafile);
1087  tls_cfg->cafile = ast_strdup(value);
1088  } else if (!strcasecmp(varname, "tlscapath") || !strcasecmp(varname, "tlscadir")) {
1089  ast_free(tls_cfg->capath);
1090  tls_cfg->capath = ast_strdup(value);
1091  } else if (!strcasecmp(varname, "tlsverifyclient")) {
1093  } else if (!strcasecmp(varname, "tlsdontverifyserver")) {
1095  } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) {
1096  if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address))
1097  ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value);
1098  } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) {
1099  if (!strcasecmp(value, "tlsv1")) {
1103  } else if (!strcasecmp(value, "sslv3")) {
1107  } else if (!strcasecmp(value, "sslv2")) {
1111  }
1112  } else {
1113  return -1;
1114  }
1115 
1116  return 0;
1117 }
char * pvtfile
Definition: tcptls.h:88
#define ast_strdup(a)
Definition: astmm.h:109
#define ast_set2_flag(p, value, flag)
Definition: utils.h:94
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
int value
Definition: syslog.c:39
int ast_parse_arg(const char *arg, enum ast_parse_flags flags, void *result,...)
The argument parsing routine.
Definition: config.c:2805
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char * cafile
Definition: tcptls.h:90
#define ast_free(a)
Definition: astmm.h:97
char * certfile
Definition: tcptls.h:87
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct ast_flags flags
Definition: tcptls.h:92
char * capath
Definition: tcptls.h:91
struct ast_sockaddr local_address
Definition: tcptls.h:124
char * cipher
Definition: tcptls.h:89
int enabled
Definition: tcptls.h:86