static struct ast_event *alloc_event(const struct ast_security_event_common *sec) { struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN); struct timeval tv = ast_tvnow(); const char *severity_str; if (check_event_type(sec->event_type)) { return NULL; } encode_timestamp(&str, &tv); severity_str = S_OR( ast_security_event_severity_get_name(sec_events[sec->event_type].severity), "Unknown" ); return ast_event_new(AST_EVENT_SECURITY, AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type, AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version, AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, ast_str_buffer(str), AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service, AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str, AST_EVENT_IE_END); }
/*! \brief Informs the cluster of our EID and our IP addresses */ static void send_cluster_notify(void) { struct ast_event *event; unsigned int node_id; cs_error_t cs_err; corosync_cfg_node_address_t corosync_addr; int num_addrs = 0; struct sockaddr *sa; size_t sa_len; char buf[128]; int res; if ((cs_err = corosync_cfg_local_get(cfg_handle, &node_id)) != CS_OK) { ast_log(LOG_WARNING, "Failed to extract Corosync node ID for this node. Not informing cluster of existance.\n"); return; } if (((cs_err = corosync_cfg_get_node_addrs(cfg_handle, node_id, 1, &num_addrs, &corosync_addr)) != CS_OK) || (num_addrs < 1)) { ast_log(LOG_WARNING, "Failed to get local Corosync address. Not informing cluster of existance.\n"); return; } sa = (struct sockaddr *)corosync_addr.address; sa_len = (size_t)corosync_addr.address_length; if ((res = getnameinfo(sa, sa_len, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST))) { ast_log(LOG_WARNING, "Failed to determine name of local Corosync address: %s (%d). Not informing cluster of existance.\n", gai_strerror(res), res); return; } event = ast_event_new(AST_EVENT_CLUSTER_DISCOVERY, AST_EVENT_IE_NODE_ID, AST_EVENT_IE_PLTYPE_UINT, node_id, AST_EVENT_IE_LOCAL_ADDR, AST_EVENT_IE_PLTYPE_STR, buf, AST_EVENT_IE_END); publish_event_to_corosync(event); ast_free(event); }
/*! \brief Convert a Corosync PING to a \ref ast_event */ static struct ast_event *corosync_ping_to_event(struct stasis_message *message) { struct corosync_ping_payload *payload; struct ast_event *event; struct ast_eid *event_eid; if (!message) { return NULL; } payload = stasis_message_data(message); if (!payload->event) { return NULL; } event_eid = (struct ast_eid *)ast_event_get_ie_raw(payload->event, AST_EVENT_IE_EID); event = ast_event_new(AST_EVENT_PING, AST_EVENT_IE_EID, AST_EVENT_IE_PLTYPE_RAW, event_eid, sizeof(*event_eid), AST_EVENT_IE_END); return event; }
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2) { struct timeval eventtime; struct ast_event *ev; const char *peername = ""; struct ast_channel *peer; ast_channel_lock(chan); peer = ast_bridged_channel(chan); if (peer) { ast_channel_ref(peer); } ast_channel_unlock(chan); /* Make sure a reload is not occurring while we're checking to see if this * is an event that we care about. We could lose an important event in this * process otherwise. */ ast_mutex_lock(&reload_lock); if (!cel_enabled || !ast_cel_track_event(event_type)) { ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_unref(peer); } return 0; } if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { char *app; if (!(app = ao2_find(appset, (char *) chan->appl, OBJ_POINTER))) { ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_unref(peer); } return 0; } ao2_ref(app, -1); } ast_mutex_unlock(&reload_lock); if (peer) { ast_channel_lock(peer); peername = ast_strdupa(peer->name); ast_channel_unlock(peer); } else if (peer2) { ast_channel_lock(peer2); peername = ast_strdupa(peer2->name); ast_channel_unlock(peer2); } if (!userdefevname) { userdefevname = ""; } if (!extra) { extra = ""; } eventtime = ast_tvnow(); ast_channel_lock(chan); ev = ast_event_new(AST_EVENT_CEL, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, ""), AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""), AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, ""), AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, ""), AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->dialed.number.str, ""), AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, chan->exten, AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, chan->context, AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, chan->name, AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->appl, ""), AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(chan->data, ""), AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, chan->amaflags, AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, chan->accountcode, AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, chan->peeraccount, AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, chan->uniqueid, AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, chan->linkedid, AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, chan->userfield, AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, AST_EVENT_IE_END); ast_channel_unlock(chan); if (peer) { peer = ast_channel_unref(peer); } if (ev && ast_event_queue(ev)) { ast_event_destroy(ev); return -1; } return 0; }
int ast_cel_report_event(struct ast_channel *chan, enum ast_cel_event_type event_type, const char *userdefevname, const char *extra, struct ast_channel *peer2) { struct timeval eventtime; struct ast_event *ev; const char *peername = ""; struct ast_channel *peer; char *linkedid = ast_strdupa(ast_channel_linkedid(chan)); /* Make sure a reload is not occurring while we're checking to see if this * is an event that we care about. We could lose an important event in this * process otherwise. */ ast_mutex_lock(&reload_lock); /* Record the linkedid of new channels if we are tracking LINKEDID_END even if we aren't * reporting on CHANNEL_START so we can track when to send LINKEDID_END */ if (cel_enabled && ast_cel_track_event(AST_CEL_LINKEDID_END) && event_type == AST_CEL_CHANNEL_START && linkedid) { if (ast_cel_linkedid_ref(linkedid)) { ast_mutex_unlock(&reload_lock); return -1; } } if (!cel_enabled || !ast_cel_track_event(event_type)) { ast_mutex_unlock(&reload_lock); return 0; } if (event_type == AST_CEL_APP_START || event_type == AST_CEL_APP_END) { char *app; if (!(app = ao2_find(appset, (char *) ast_channel_appl(chan), OBJ_POINTER))) { ast_mutex_unlock(&reload_lock); return 0; } ao2_ref(app, -1); } ast_mutex_unlock(&reload_lock); ast_channel_lock(chan); peer = ast_bridged_channel(chan); if (peer) { ast_channel_ref(peer); } ast_channel_unlock(chan); if (peer) { ast_channel_lock(peer); peername = ast_strdupa(ast_channel_name(peer)); ast_channel_unlock(peer); } else if (peer2) { ast_channel_lock(peer2); peername = ast_strdupa(ast_channel_name(peer2)); ast_channel_unlock(peer2); } if (!userdefevname) { userdefevname = ""; } if (!extra) { extra = ""; } eventtime = ast_tvnow(); ast_channel_lock(chan); ev = ast_event_new(AST_EVENT_CEL, AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type, AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec, AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec, AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, userdefevname, AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->id.name.valid, ast_channel_caller(chan)->id.name.str, ""), AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, ""), AST_EVENT_IE_CEL_CIDANI, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_caller(chan)->ani.number.valid, ast_channel_caller(chan)->ani.number.str, ""), AST_EVENT_IE_CEL_CIDRDNIS, AST_EVENT_IE_PLTYPE_STR, S_COR(ast_channel_redirecting(chan)->from.number.valid, ast_channel_redirecting(chan)->from.number.str, ""), AST_EVENT_IE_CEL_CIDDNID, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_dialed(chan)->number.str, ""), AST_EVENT_IE_CEL_EXTEN, AST_EVENT_IE_PLTYPE_STR, ast_channel_exten(chan), AST_EVENT_IE_CEL_CONTEXT, AST_EVENT_IE_PLTYPE_STR, ast_channel_context(chan), AST_EVENT_IE_CEL_CHANNAME, AST_EVENT_IE_PLTYPE_STR, ast_channel_name(chan), AST_EVENT_IE_CEL_APPNAME, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_appl(chan), ""), AST_EVENT_IE_CEL_APPDATA, AST_EVENT_IE_PLTYPE_STR, S_OR(ast_channel_data(chan), ""), AST_EVENT_IE_CEL_AMAFLAGS, AST_EVENT_IE_PLTYPE_UINT, ast_channel_amaflags(chan), AST_EVENT_IE_CEL_ACCTCODE, AST_EVENT_IE_PLTYPE_STR, ast_channel_accountcode(chan), AST_EVENT_IE_CEL_PEERACCT, AST_EVENT_IE_PLTYPE_STR, ast_channel_peeraccount(chan), AST_EVENT_IE_CEL_UNIQUEID, AST_EVENT_IE_PLTYPE_STR, ast_channel_uniqueid(chan), AST_EVENT_IE_CEL_LINKEDID, AST_EVENT_IE_PLTYPE_STR, ast_channel_linkedid(chan), AST_EVENT_IE_CEL_USERFIELD, AST_EVENT_IE_PLTYPE_STR, ast_channel_userfield(chan), AST_EVENT_IE_CEL_EXTRA, AST_EVENT_IE_PLTYPE_STR, extra, AST_EVENT_IE_CEL_PEER, AST_EVENT_IE_PLTYPE_STR, peername, AST_EVENT_IE_END); ast_channel_unlock(chan); if (peer) { peer = ast_channel_unref(peer); } if (ev && ast_event_queue(ev)) { ast_event_destroy(ev); return -1; } return 0; }
/* \brief called by scheduler to send STUN request */ static int stun_monitor_request(const void *blarg) { int res; struct sockaddr_in answer; static const struct sockaddr_in no_addr = { 0, }; ast_mutex_lock(&args.lock); if (!args.monitor_enabled) { goto monitor_request_cleanup; } if (args.stun_sock < 0) { struct ast_sockaddr stun_addr; /* STUN socket not open. Refresh the server DNS address resolution. */ if (!args.server_hostname) { /* No STUN hostname? */ goto monitor_request_cleanup; } /* Lookup STUN address. */ memset(&stun_addr, 0, sizeof(stun_addr)); stun_addr.ss.ss_family = AF_INET; if (ast_get_ip(&stun_addr, args.server_hostname)) { /* Lookup failed. */ ast_log(LOG_WARNING, "Unable to lookup STUN server '%s'\n", args.server_hostname); goto monitor_request_cleanup; } ast_sockaddr_set_port(&stun_addr, args.stun_port); /* open socket binding */ args.stun_sock = socket(AF_INET, SOCK_DGRAM, 0); if (args.stun_sock < 0) { ast_log(LOG_WARNING, "Unable to create STUN socket: %s\n", strerror(errno)); goto monitor_request_cleanup; } if (ast_connect(args.stun_sock, &stun_addr)) { ast_log(LOG_WARNING, "STUN Failed to connect to %s: %s\n", ast_sockaddr_stringify(&stun_addr), strerror(errno)); stun_close_sock(); goto monitor_request_cleanup; } } res = ast_stun_request(args.stun_sock, NULL, NULL, &answer); if (res) { /* * STUN request timed out or errored. * * Refresh the server DNS address resolution next time around. */ if (!args.stun_poll_failed_gripe) { args.stun_poll_failed_gripe = 1; ast_log(LOG_WARNING, "STUN poll %s. Re-evaluating STUN server address.\n", res < 0 ? "failed" : "got no response"); } stun_close_sock(); } else { args.stun_poll_failed_gripe = 0; if (memcmp(&no_addr, &answer, sizeof(no_addr)) && memcmp(&args.external_addr, &answer, sizeof(args.external_addr))) { const char *newaddr = ast_strdupa(ast_inet_ntoa(answer.sin_addr)); int newport = ntohs(answer.sin_port); ast_log(LOG_NOTICE, "Old external address/port %s:%d now seen as %s:%d.\n", ast_inet_ntoa(args.external_addr.sin_addr), ntohs(args.external_addr.sin_port), newaddr, newport); args.external_addr = answer; if (args.external_addr_known) { struct ast_event *event; /* * The external address was already known, and has changed... * generate event. */ event = ast_event_new(AST_EVENT_NETWORK_CHANGE, AST_EVENT_IE_END); if (!event) { ast_log(LOG_ERROR, "Could not create AST_EVENT_NETWORK_CHANGE event.\n"); } else if (ast_event_queue(event)) { ast_event_destroy(event); ast_log(LOG_ERROR, "Could not queue AST_EVENT_NETWORK_CHANGE event.\n"); } } else { /* this was the first external address we found, do not alert listeners * until this address changes to something else. */ args.external_addr_known = 1; } } } monitor_request_cleanup: /* always refresh this scheduler item. It will be removed elsewhere when * it is supposed to go away */ res = args.refresh * 1000; ast_mutex_unlock(&args.lock); return res; }