struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_session_args *desc) { int x = 1; struct ast_tcptls_session_instance *tcptls_session = NULL; /* Do nothing if nothing has changed */ if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) { ast_debug(1, "Nothing changed in %s\n", desc->name); return NULL; } /* If we return early, there is no connection */ ast_sockaddr_setnull(&desc->old_address); if (desc->accept_fd != -1) close(desc->accept_fd); desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ? AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP); if (desc->accept_fd < 0) { ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno)); return NULL; } /* if a local address was specified, bind to it so the connection will originate from the desired address */ if (!ast_sockaddr_isnull(&desc->local_address)) { setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ast_bind(desc->accept_fd, &desc->local_address)) { ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n", desc->name, ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } } if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) goto error; ast_mutex_init(&tcptls_session->lock); tcptls_session->client = 1; tcptls_session->fd = desc->accept_fd; tcptls_session->parent = desc; tcptls_session->parent->worker_fn = NULL; ast_sockaddr_copy(&tcptls_session->remote_address, &desc->remote_address); /* Set current info */ ast_sockaddr_copy(&desc->old_address, &desc->remote_address); return tcptls_session; error: close(desc->accept_fd); desc->accept_fd = -1; if (tcptls_session) ao2_ref(tcptls_session, -1); return NULL; }
/*! \brief Function called when we should prepare to call the destination */ static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) { char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control; struct ast_rtp_instance *instance; struct ast_sockaddr control_address; struct ast_sockaddr destination_address; struct ast_channel *chan; format_t fmt = ast_best_codec(format); ast_sockaddr_setnull(&control_address); /* If no type was given we can't do anything */ if (ast_strlen_zero(multicast_type)) { goto failure; } if (!(destination = strchr(tmp, '/'))) { goto failure; } *destination++ = '\0'; if ((control = strchr(destination, '/'))) { *control++ = '\0'; if (!ast_sockaddr_parse(&control_address, control, PARSE_PORT_REQUIRE)) { goto failure; } } if (!ast_sockaddr_parse(&destination_address, destination, PARSE_PORT_REQUIRE)) { goto failure; } if (!(instance = ast_rtp_instance_new("multicast", NULL, &control_address, multicast_type))) { goto failure; } if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", requestor ? requestor->linkedid : "", 0, "MulticastRTP/%p", instance))) { ast_rtp_instance_destroy(instance); goto failure; } ast_rtp_instance_set_remote_address(instance, &destination_address); chan->tech = &multicast_rtp_tech; chan->nativeformats = fmt; chan->writeformat = fmt; chan->readformat = fmt; chan->rawwriteformat = fmt; chan->rawreadformat = fmt; chan->tech_pvt = instance; return chan; failure: *cause = AST_CAUSE_FAILURE; return NULL; }
static void check_debug(void) { RAII_VAR(char *, debug, ast_sip_get_debug(), ast_free); if (ast_false(debug)) { logging_mode = LOGGING_MODE_DISABLED; return; } logging_mode = LOGGING_MODE_ENABLED; if (ast_true(debug)) { ast_sockaddr_setnull(&log_addr); return; } /* assume host */ if (ast_sockaddr_resolve_first_af(&log_addr, debug, 0, AST_AF_UNSPEC)) { ast_log(LOG_WARNING, "Could not resolve host %s for debug " "logging\n", debug); } }
static char *pjsip_set_logger(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { const char *what; if (cmd == CLI_INIT) { e->command = "pjsip set logger {on|off|host}"; e->usage = "Usage: pjsip set logger {on|off|host <name>}\n" " Enables or disabling logging of SIP packets\n" " read on ports bound to PJSIP transports either\n" " globally or enables logging for an individual\n" " host.\n"; return NULL; } else if (cmd == CLI_GENERATE) { return NULL; } what = a->argv[e->args - 1]; /* Guaranteed to exist */ if (a->argc == e->args) { /* on/off */ if (!strcasecmp(what, "on")) { logging_mode = LOGGING_MODE_ENABLED; ast_cli(a->fd, "PJSIP Logging enabled\n"); ast_sockaddr_setnull(&log_addr); return CLI_SUCCESS; } else if (!strcasecmp(what, "off")) { logging_mode = LOGGING_MODE_DISABLED; ast_cli(a->fd, "PJSIP Logging disabled\n"); return CLI_SUCCESS; } } else if (a->argc == e->args + 1) { if (!strcasecmp(what, "host")) { return pjsip_enable_logger_host(a->fd, a->argv[e->args]); } } return CLI_SHOWUSAGE; }
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) { int flags; int x = 1; /* Do nothing if nothing has changed */ if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) { ast_debug(1, "Nothing changed in %s\n", desc->name); return; } /* If we return early, there is no one listening */ ast_sockaddr_setnull(&desc->old_address); /* Shutdown a running server if there is one */ if (desc->master != AST_PTHREADT_NULL) { pthread_cancel(desc->master); pthread_kill(desc->master, SIGURG); pthread_join(desc->master, NULL); } if (desc->accept_fd != -1) { close(desc->accept_fd); } /* If there's no new server, stop here */ if (ast_sockaddr_isnull(&desc->local_address)) { ast_debug(2, "Server disabled: %s\n", desc->name); return; } desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); if (desc->accept_fd < 0) { ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno)); return; } setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ast_bind(desc->accept_fd, &desc->local_address)) { ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n", desc->name, ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } if (listen(desc->accept_fd, 10)) { ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name); goto error; } flags = fcntl(desc->accept_fd, F_GETFL); fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) { ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n", desc->name, ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } /* Set current info */ ast_sockaddr_copy(&desc->old_address, &desc->local_address); return; error: close(desc->accept_fd); desc->accept_fd = -1; }
/*! \brief Function called when we should prepare to call the destination */ static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause) { char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control; struct ast_rtp_instance *instance; struct ast_sockaddr control_address; struct ast_sockaddr destination_address; struct ast_channel *chan; struct ast_format fmt; ast_best_codec(cap, &fmt); ast_sockaddr_setnull(&control_address); /* If no type was given we can't do anything */ if (ast_strlen_zero(multicast_type)) { goto failure; } if (!(destination = strchr(tmp, '/'))) { goto failure; } *destination++ = '\0'; if ((control = strchr(destination, '/'))) { *control++ = '\0'; if (!ast_sockaddr_parse(&control_address, control, PARSE_PORT_REQUIRE)) { goto failure; } } if (!ast_sockaddr_parse(&destination_address, destination, PARSE_PORT_REQUIRE)) { goto failure; } if (!(instance = ast_rtp_instance_new("multicast", NULL, &control_address, multicast_type))) { goto failure; } if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", requestor ? ast_channel_linkedid(requestor) : "", 0, "MulticastRTP/%p", instance))) { ast_rtp_instance_destroy(instance); goto failure; } ast_rtp_instance_set_channel_id(instance, ast_channel_uniqueid(chan)); ast_rtp_instance_set_remote_address(instance, &destination_address); ast_channel_tech_set(chan, &multicast_rtp_tech); ast_format_cap_add(ast_channel_nativeformats(chan), &fmt); ast_format_copy(ast_channel_writeformat(chan), &fmt); ast_format_copy(ast_channel_rawwriteformat(chan), &fmt); ast_format_copy(ast_channel_readformat(chan), &fmt); ast_format_copy(ast_channel_rawreadformat(chan), &fmt); ast_channel_tech_pvt_set(chan, instance); return chan; failure: *cause = AST_CAUSE_FAILURE; return NULL; }
void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) { int flags; int x = 1; int tls_changed = 0; if (desc->tls_cfg) { char hash[41]; char *str = NULL; struct stat st; /* Store the hashes of the TLS certificate etc. */ if (stat(desc->tls_cfg->certfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->certfile))) { memset(hash, 0, 41); } else { ast_sha1_hash(hash, str); } ast_free(str); str = NULL; memcpy(desc->tls_cfg->certhash, hash, 41); if (stat(desc->tls_cfg->pvtfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->pvtfile))) { memset(hash, 0, 41); } else { ast_sha1_hash(hash, str); } ast_free(str); str = NULL; memcpy(desc->tls_cfg->pvthash, hash, 41); if (stat(desc->tls_cfg->cafile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->cafile))) { memset(hash, 0, 41); } else { ast_sha1_hash(hash, str); } ast_free(str); str = NULL; memcpy(desc->tls_cfg->cahash, hash, 41); /* Check whether TLS configuration has changed */ if (!desc->old_tls_cfg) { /* No previous configuration */ tls_changed = 1; desc->old_tls_cfg = ast_calloc(1, sizeof(*desc->old_tls_cfg)); } else if (memcmp(desc->tls_cfg->certhash, desc->old_tls_cfg->certhash, 41)) { tls_changed = 1; } else if (memcmp(desc->tls_cfg->pvthash, desc->old_tls_cfg->pvthash, 41)) { tls_changed = 1; } else if (strcmp(desc->tls_cfg->cipher, desc->old_tls_cfg->cipher)) { tls_changed = 1; } else if (memcmp(desc->tls_cfg->cahash, desc->old_tls_cfg->cahash, 41)) { tls_changed = 1; } else if (strcmp(desc->tls_cfg->capath, desc->old_tls_cfg->capath)) { tls_changed = 1; } else if (memcmp(&desc->tls_cfg->flags, &desc->old_tls_cfg->flags, sizeof(desc->tls_cfg->flags))) { tls_changed = 1; } if (tls_changed) { ast_debug(1, "Changed parameters for %s found\n", desc->name); } } /* Do nothing if nothing has changed */ if (!tls_changed && !ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) { ast_debug(1, "Nothing changed in %s\n", desc->name); return; } /* If we return early, there is no one listening */ ast_sockaddr_setnull(&desc->old_address); /* Shutdown a running server if there is one */ if (desc->master != AST_PTHREADT_NULL) { pthread_cancel(desc->master); pthread_kill(desc->master, SIGURG); pthread_join(desc->master, NULL); } if (desc->accept_fd != -1) { close(desc->accept_fd); } /* If there's no new server, stop here */ if (ast_sockaddr_isnull(&desc->local_address)) { ast_debug(2, "Server disabled: %s\n", desc->name); return; } desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ? AF_INET6 : AF_INET, SOCK_STREAM, 0); if (desc->accept_fd < 0) { ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno)); return; } setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); if (ast_bind(desc->accept_fd, &desc->local_address)) { ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n", desc->name, ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } if (listen(desc->accept_fd, 10)) { ast_log(LOG_ERROR, "Unable to listen for %s!\n", desc->name); goto error; } flags = fcntl(desc->accept_fd, F_GETFL); fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) { ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n", desc->name, ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } /* Set current info */ ast_sockaddr_copy(&desc->old_address, &desc->local_address); if (desc->old_tls_cfg) { ast_free(desc->old_tls_cfg->certfile); ast_free(desc->old_tls_cfg->pvtfile); ast_free(desc->old_tls_cfg->cipher); ast_free(desc->old_tls_cfg->cafile); ast_free(desc->old_tls_cfg->capath); desc->old_tls_cfg->certfile = ast_strdup(desc->tls_cfg->certfile); desc->old_tls_cfg->pvtfile = ast_strdup(desc->tls_cfg->pvtfile); desc->old_tls_cfg->cipher = ast_strdup(desc->tls_cfg->cipher); desc->old_tls_cfg->cafile = ast_strdup(desc->tls_cfg->cafile); desc->old_tls_cfg->capath = ast_strdup(desc->tls_cfg->capath); memcpy(desc->old_tls_cfg->certhash, desc->tls_cfg->certhash, 41); memcpy(desc->old_tls_cfg->pvthash, desc->tls_cfg->pvthash, 41); memcpy(desc->old_tls_cfg->cahash, desc->tls_cfg->cahash, 41); memcpy(&desc->old_tls_cfg->flags, &desc->tls_cfg->flags, sizeof(desc->old_tls_cfg->flags)); } return; error: close(desc->accept_fd); desc->accept_fd = -1; }