char *__netsock_stringify_fmt(const struct sockaddr_storage *sockAddrStorage, int format) { const struct sockaddr_storage *sockAddrStorage_tmp; char host[NI_MAXHOST] = ""; char port[NI_MAXSERV] = ""; struct ast_str *str; int e; static const size_t size = sizeof(host) - 1 + sizeof(port) - 1 + 4; if (!sockAddrStorage) { return "(null)"; } if (!(str = ast_str_thread_get(&sccp_netsock_stringify_buf, size))) { return ""; } //if (sccp_netsock_ipv4_mapped(sockAddrStorage, &sockAddrStorage_tmp_ipv4)) { // struct sockaddr_storage sockAddrStorage_tmp_ipv4; // sockAddrStorage_tmp = &sockAddrStorage_tmp_ipv4; //#if DEBUG // sccp_log(0)("SCCP: ipv4 mapped in ipv6 address\n"); //#endif //} else { sockAddrStorage_tmp = sockAddrStorage; //} if ((e = getnameinfo((struct sockaddr *) sockAddrStorage_tmp, sccp_netsock_sizeof(sockAddrStorage_tmp), format & SCCP_SOCKADDR_STR_ADDR ? host : NULL, format & SCCP_SOCKADDR_STR_ADDR ? sizeof(host) : 0, format & SCCP_SOCKADDR_STR_PORT ? port : 0, format & SCCP_SOCKADDR_STR_PORT ? sizeof(port) : 0, NI_NUMERICHOST | NI_NUMERICSERV))) { sccp_log(DEBUGCAT_SOCKET) (VERBOSE_PREFIX_3 "SCCP: getnameinfo(): %s \n", gai_strerror(e)); return ""; } if ((format & SCCP_SOCKADDR_STR_REMOTE) == SCCP_SOCKADDR_STR_REMOTE) { char *p; if (sccp_netsock_is_ipv6_link_local(sockAddrStorage_tmp) && (p = strchr(host, '%'))) { *p = '\0'; } } switch ((format & SCCP_SOCKADDR_STR_FORMAT_MASK)) { case SCCP_SOCKADDR_STR_DEFAULT: ast_str_set(&str, 0, sockAddrStorage_tmp->ss_family == AF_INET6 ? "[%s]:%s" : "%s:%s", host, port); break; case SCCP_SOCKADDR_STR_ADDR: ast_str_set(&str, 0, "%s", host); break; case SCCP_SOCKADDR_STR_HOST: ast_str_set(&str, 0, sockAddrStorage_tmp->ss_family == AF_INET6 ? "[%s]" : "%s", host); break; case SCCP_SOCKADDR_STR_PORT: ast_str_set(&str, 0, "%s", port); break; default: pbx_log(LOG_ERROR, "Invalid format\n"); return ""; } return ast_str_buffer(str); }
/*! * \brief Fire an Event * \param event SCCP Event * \note event will be freed after event is fired * * \warning * - sccp_event_listeners->subscriber is not always locked */ void sccp_event_fire(const sccp_event_t * event) { if (event == NULL || SCCP_REF_RUNNING != sccp_refcount_isRunning() || !sccp_event_running) { if (event) { sccp_event_destroy((sccp_event_t *) event); } return; } AUTO_RELEASE sccp_event_t *e = (sccp_event_t *) sccp_refcount_object_alloc(sizeof(sccp_event_t), SCCP_REF_EVENT, sccp_event_type2str(event->type), sccp_event_destroy); if (!e) { pbx_log(LOG_ERROR, "%p: Memory Allocation Error while creating sccp_event e. Exiting\n", event); sccp_event_destroy((sccp_event_t *) event); return; } // memcpy(e, event, sizeof(sccp_event_t)); e->type = event->type; sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Handling Event %p of Type %s\n", event, sccp_event_type2str(e->type)); /* update refcount */ switch (e->type) { case SCCP_EVENT_DEVICE_REGISTERED: case SCCP_EVENT_DEVICE_UNREGISTERED: case SCCP_EVENT_DEVICE_PREREGISTERED: e->event.deviceRegistered.device = event->event.deviceRegistered.device; break; case SCCP_EVENT_LINE_CREATED: e->event.lineCreated.line = event->event.lineCreated.line; break; case SCCP_EVENT_DEVICE_ATTACHED: case SCCP_EVENT_DEVICE_DETACHED: e->event.deviceAttached.linedevice = event->event.deviceAttached.linedevice; break; case SCCP_EVENT_FEATURE_CHANGED: e->event.featureChanged.device = event->event.featureChanged.device; e->event.featureChanged.optional_linedevice = event->event.featureChanged.optional_linedevice; e->event.featureChanged.featureType = event->event.featureChanged.featureType; break; case SCCP_EVENT_LINESTATUS_CHANGED: e->event.lineStatusChanged.line = event->event.lineStatusChanged.line; e->event.lineStatusChanged.optional_device = event->event.lineStatusChanged.optional_device; e->event.lineStatusChanged.state = event->event.lineStatusChanged.state; break; case SCCP_EVENT_LINE_CHANGED: case SCCP_EVENT_LINE_DELETED: break; case SCCP_EVENT_TYPE_SENTINEL: break; } /* search for position in array */ int i, n; sccp_event_type_t eventType = event->type; for (i = 0, n = 1 << i; i < NUMBER_OF_EVENT_TYPES; i++, n = 1 << i) { if (eventType & n) { break; } } // pthread_attr_t tattr; // pthread_t tid; /* start async thread if nessesary */ if (GLOB(module_running)) { if (subscriptions[i].aSyncSize > 0 && sccp_event_running) { /* create thread for async subscribers */ struct sccp_event_aSyncEventProcessorThreadArg *arg = sccp_malloc(sizeof(struct sccp_event_aSyncEventProcessorThreadArg)); if (!arg) { pbx_log(LOG_ERROR, "%p: Memory Allocation Error while creating sccp_event_aSyncEventProcessorThreadArg. Skipping\n", event); } else { arg->subscribers = &subscriptions[i]; arg->event = sccp_event_retain(e); /* initialized with default attributes */ if (arg->event != NULL) { sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Adding work to threadpool for event: %p, type: %s\n", event, sccp_event_type2str(event->type)); if (!sccp_threadpool_add_work(GLOB(general_threadpool), (void *) sccp_event_processor, (void *) arg)) { pbx_log(LOG_ERROR, "Could not add work to threadpool for event: %p, type: %s for processing\n", event, sccp_event_type2str(event->type)); arg->event = sccp_event_release(arg->event); sccp_free(arg); } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); sccp_free(arg); } } } /* execute sync subscribers */ AUTO_RELEASE sccp_event_t *tmp_e = NULL; if ((tmp_e = sccp_event_retain(e))) { for (n = 0; n < subscriptions[i].syncSize && sccp_event_running; n++) { if (subscriptions[i].sync[n].callback_function != NULL) { subscriptions[i].sync[n].callback_function((const sccp_event_t *) e); } } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); } } else { // we are unloading. switching to synchonous mode for everything sccp_log((DEBUGCAT_EVENT)) (VERBOSE_PREFIX_3 "Handling Event %p of Type %s in Forced Synchronous Mode\n", event, sccp_event_type2str(e->type)); AUTO_RELEASE sccp_event_t *tmp_e = NULL; if ((tmp_e = sccp_event_retain(e))) { for (n = 0; n < subscriptions[i].syncSize && sccp_event_running; n++) { if (subscriptions[i].sync[n].callback_function != NULL) { subscriptions[i].sync[n].callback_function((const sccp_event_t *) e); } } for (n = 0; n < subscriptions[i].aSyncSize && sccp_event_running; n++) { if (subscriptions[i].async[n].callback_function != NULL) { subscriptions[i].async[n].callback_function((const sccp_event_t *) e); } } } else { pbx_log(LOG_ERROR, "Could not retain e: %p, type: %s for processing\n", e, sccp_event_type2str(event->type)); } } }
/*! * \brief * Splits a string into its host and port components * * \param str [in] The string to parse. May be modified by writing a NUL at the end of * the host part. * \param host [out] Pointer to the host component within \a str. * \param port [out] Pointer to the port component within \a str. * \param flags If set to zero, a port MAY be present. If set to PARSE_PORT_IGNORE, a * port MAY be present but will be ignored. If set to PARSE_PORT_REQUIRE, * a port MUST be present. If set to PARSE_PORT_FORBID, a port MUST NOT * be present. * * \retval 1 Success * \retval 0 Failure */ int sccp_netsock_split_hostport(char *str, char **host, char **port, int flags) { char *s = str; char *orig_str = str; /* Original string in case the port presence is incorrect. */ char *host_end = NULL; /* Delay terminating the host in case the port presence is incorrect. */ sccp_log(DEBUGCAT_HIGH) (VERBOSE_PREFIX_4 "Splitting '%s' into...\n", str); *host = NULL; *port = NULL; if (*s == '[') { *host = ++s; for (; *s && *s != ']'; ++s) { } if (*s == ']') { host_end = s; ++s; } if (*s == ':') { *port = s + 1; } } else { *host = s; for (; *s; ++s) { if (*s == ':') { if (*port) { *port = NULL; break; } else { *port = s; } } } if (*port) { host_end = *port; ++*port; } } switch (flags & PARSE_PORT_MASK) { case PARSE_PORT_IGNORE: *port = NULL; break; case PARSE_PORT_REQUIRE: if (*port == NULL) { pbx_log(LOG_WARNING, "Port missing in %s\n", orig_str); return 0; } break; case PARSE_PORT_FORBID: if (*port != NULL) { pbx_log(LOG_WARNING, "Port disallowed in %s\n", orig_str); return 0; } break; } /* Can terminate the host string now if needed. */ if (host_end) { *host_end = '\0'; } sccp_log(DEBUGCAT_HIGH) (VERBOSE_PREFIX_4 "...host '%s' and port '%s'.\n", *host, *port ? *port : ""); return 1; }