X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=coreapi%2Fupnp.c;h=0922dad59eb7aa7c66d8f7517da589715f2c1422;hb=9b7ac9b79375f845edd0e8366e602863a223d2c0;hp=596afe3338ecfa53ac81aa298c6ec8183c67620f;hpb=837c566c0a2cfd5d27d738f1647872703786d6cd;p=linphone diff --git a/coreapi/upnp.c b/coreapi/upnp.c index 596afe33..0922dad5 100644 --- a/coreapi/upnp.c +++ b/coreapi/upnp.c @@ -29,9 +29,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define UPNP_REMOVE_MAX_RETRY 4 #define UPNP_SECTION_NAME "uPnP" #define UPNP_CORE_READY_CHECK 1 -#define UPNP_CORE_RETRY_DELAY 4 -#define UPNP_CALL_RETRY_DELAY 1 -#define UPNP_UUID_LEN 32 +#define UPNP_CORE_RETRY_DELAY 10 +#define UPNP_CALL_RETRY_DELAY 3 +#define UPNP_UUID_LEN 128 #define UPNP_UUID_LEN_STR UPNP_TOSTRING(UPNP_UUID_LEN) /* * uPnP Definitions @@ -111,22 +111,22 @@ void linphone_upnp_config_remove_port_binding(UpnpContext *lupnp, const UpnpPort int linphone_upnp_context_send_remove_port_binding(UpnpContext *lupnp, UpnpPortBinding *port, bool_t retry); int linphone_upnp_context_send_add_port_binding(UpnpContext *lupnp, UpnpPortBinding *port, bool_t retry); - static int linphone_upnp_strncmpi(const char *str1, const char *str2, int len) { int i = 0; char char1, char2; - while(*str1 != '\0' && *str2 != '\0' && i < len) { + while(i < len) { char1 = toupper(*str1); char2 = toupper(*str2); - if(char1 != char2) { + if(char1 == '\0' || char1 != char2) { return char1 - char2; } str1++; str2++; - len++; + i++; } return 0; } + static int linphone_upnp_str_min(const char *str1, const char *str2) { int len1 = strlen(str1); int len2 = strlen(str2); @@ -135,6 +135,7 @@ static int linphone_upnp_str_min(const char *str1, const char *str2) { } return len1; } + char * linphone_upnp_format_device_id(const char *device_id) { char *ret = NULL; char *tmp; @@ -337,7 +338,7 @@ UpnpContext* linphone_upnp_context_new(LinphoneCore *lc) { linphone_core_add_iterate_hook(lc, linphone_core_upnp_hook, lupnp); lupnp->upnp_igd_ctxt = NULL; - lupnp->upnp_igd_ctxt = upnp_igd_create(linphone_upnp_igd_callback, linphone_upnp_igd_print, lupnp); + lupnp->upnp_igd_ctxt = upnp_igd_create(linphone_upnp_igd_callback, linphone_upnp_igd_print, NULL, lupnp); if(lupnp->upnp_igd_ctxt == NULL) { lupnp->state = LinphoneUpnpStateKo; ms_error("Can't create uPnP IGD context"); @@ -552,9 +553,8 @@ int linphone_upnp_context_send_add_port_binding(UpnpContext *lupnp, UpnpPortBind mapping.local_port = port->local_port; mapping.local_host = port->local_addr; if(port->external_port == -1) - mapping.remote_port = rand()%(0xffff - 1024) + 1024; - else - mapping.remote_port = port->external_port; + port->external_port = rand()%(0xffff - 1024) + 1024; + mapping.remote_port = port->external_port; mapping.remote_host = ""; snprintf(description, 128, "%s %s at %s:%d", PACKAGE_NAME, @@ -1053,11 +1053,17 @@ UpnpPortBinding *linphone_upnp_port_binding_new_with_parameters(upnp_igd_ip_prot UpnpPortBinding *linphone_upnp_port_binding_new_or_collect(MSList *list, upnp_igd_ip_protocol protocol, int local_port, int external_port) { UpnpPortBinding *tmp_binding; UpnpPortBinding *end_binding; - end_binding = linphone_upnp_port_binding_new_with_parameters(protocol, local_port, external_port); + + // Seek an binding with same protocol and local port + end_binding = linphone_upnp_port_binding_new_with_parameters(protocol, local_port, -1); tmp_binding = linphone_upnp_port_binding_equivalent_in_list(list, end_binding); - if(tmp_binding != NULL) { + + // Must be not attached to any struct + if(tmp_binding != NULL && tmp_binding->ref == 1) { linphone_upnp_port_binding_release(end_binding); - end_binding = tmp_binding; + end_binding = linphone_upnp_port_binding_retain(tmp_binding); + } else { + end_binding->external_port = external_port; } return end_binding; } @@ -1104,10 +1110,11 @@ void linphone_upnp_port_binding_log(int level, const char *msg, const UpnpPortBi } } +// Return true if the binding are equivalent. (Note external_port == -1 means "don't care") bool_t linphone_upnp_port_binding_equal(const UpnpPortBinding *port1, const UpnpPortBinding *port2) { return port1->protocol == port2->protocol && - port1->local_port == port2->local_port && - port1->external_port == port2->external_port; + port1->local_port == port2->local_port && + (port1->external_port == -1 || port2->external_port == -1 || port1->external_port == port2->external_port); } UpnpPortBinding *linphone_upnp_port_binding_equivalent_in_list(MSList *list, const UpnpPortBinding *port) { @@ -1235,7 +1242,7 @@ static void linphone_upnp_config_list_port_bindings_cb(const char *entry, struct bool_t valid = TRUE; UpnpPortBinding *port; - ret = sscanf(entry, "%"UPNP_UUID_LEN_STR"s-%3s-%i-%i", device_id, protocol_str, &external_port, &local_port); + ret = sscanf(entry, "%"UPNP_UUID_LEN_STR"[^-]-%3s-%i-%i", device_id, protocol_str, &external_port, &local_port); if(ret == 4) { // Handle only wanted device bindings if(device_id != NULL && strcmp(cookie->device_id, device_id) != 0) {