Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
/*! \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;
}
Exemplo n.º 3
0
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);
	}
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
/*! \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;
}
Exemplo n.º 7
0
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;
}