char* mupnp_net_selectaddr(struct sockaddr* remoteaddr) { mUpnpNetworkInterfaceList* netIfList; mUpnpNetworkInterface* netIf; mUpnpNetworkInterface* selectNetIf; char* selectNetIfAddr; u_long laddr, lmask, raddr; struct addrinfo hints; struct addrinfo* netIfAddrInfo; struct addrinfo* netMaskAddrInfo; netIfList = mupnp_net_interfacelist_new(); if (!netIfList) return mupnp_strdup("127.0.0.1"); if (mupnp_net_gethostinterfaces(netIfList) <= 0) { mupnp_net_interfacelist_delete(netIfList); return mupnp_strdup("127.0.0.1"); } raddr = ntohl(((struct sockaddr_in*)remoteaddr)->sin_addr.s_addr); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; selectNetIf = NULL; if (1 <= mupnp_net_gethostinterfaces(netIfList)) { for (netIf = mupnp_net_interfacelist_gets(netIfList); netIf; netIf = mupnp_net_interface_next(netIf)) { if (getaddrinfo(mupnp_net_interface_getaddress(netIf), NULL, &hints, &netIfAddrInfo) != 0) continue; if (getaddrinfo(mupnp_net_interface_getnetmask(netIf), NULL, &hints, &netMaskAddrInfo) != 0) { freeaddrinfo(netIfAddrInfo); continue; } laddr = ntohl(((struct sockaddr_in*)netIfAddrInfo->ai_addr)->sin_addr.s_addr); lmask = ntohl(((struct sockaddr_in*)netMaskAddrInfo->ai_addr)->sin_addr.s_addr); if ((laddr & lmask) == (raddr & lmask)) selectNetIf = netIf; freeaddrinfo(netIfAddrInfo); freeaddrinfo(netMaskAddrInfo); if (selectNetIf) break; } } if (!selectNetIf) selectNetIf = mupnp_net_interfacelist_gets(netIfList); selectNetIfAddr = mupnp_strdup(mupnp_net_interface_getaddress(selectNetIf)); mupnp_net_interfacelist_delete(netIfList); return selectNetIfAddr; }
/** * Create a new control point. Does not start any threads. * * @return A newly-created mUpnpControlPoint */ mUpnpControlPoint *mupnp_controlpoint_new() { mUpnpControlPoint *ctrlPoint; mupnp_log_debug_l4("Entering...\n"); ctrlPoint = (mUpnpControlPoint *)malloc(sizeof(mUpnpControlPoint)); if ( NULL != ctrlPoint ) { #ifdef MUPNP_HTTP_USE_PERSISTENT_CONNECTIONS mupnp_http_persistentconnection_init(); #endif ctrlPoint->mutex = mupnp_mutex_new(); ctrlPoint->deviceRootNodeList = mupnp_xml_nodelist_new(); ctrlPoint->deviceList = mupnp_devicelist_new(); ctrlPoint->ssdpServerList = mupnp_ssdp_serverlist_new(); ctrlPoint->ssdpResServerList = mupnp_ssdpresponse_serverlist_new(); ctrlPoint->httpServerList = mupnp_http_serverlist_new(); ctrlPoint->httpEventURI = mupnp_string_new(); ctrlPoint->eventListeners = mupnp_eventlistenerlist_new(); /* Expiration handling */ ctrlPoint->expThread = mupnp_thread_new(); mupnp_thread_setaction(ctrlPoint->expThread, mupnp_controlpoint_expirationhandler); mupnp_thread_setuserdata(ctrlPoint->expThread, ctrlPoint); ctrlPoint->expMutex = mupnp_mutex_new(); ctrlPoint->expCond = mupnp_cond_new(); ctrlPoint->ifCache = mupnp_net_interfacelist_new(); mupnp_controlpoint_setssdplistener(ctrlPoint, NULL); mupnp_controlpoint_setssdpresponselistener(ctrlPoint, NULL); mupnp_controlpoint_sethttplistener(ctrlPoint, NULL); mupnp_controlpoint_setdevicelistener(ctrlPoint, NULL); mupnp_controlpoint_setssdpresponseport(ctrlPoint, MUPNP_CONTROLPOINT_SSDP_RESPONSE_DEFAULT_PORT); mupnp_controlpoint_setssdpsearchmx(ctrlPoint, MUPNP_CONTROLPOINT_SSDP_DEFAULT_SEARCH_MX); mupnp_controlpoint_seteventport(ctrlPoint, MUPNP_CONTROLPOINT_HTTP_EVENT_DEFAULT_PORT); mupnp_controlpoint_seteventsuburi(ctrlPoint, MUPNP_CONTROLPOINT_HTTP_EVENTSUB_URI); mupnp_controlpoint_setuserdata(ctrlPoint, NULL); } mupnp_log_debug_l4("Leaving...\n"); return ctrlPoint; }
bool mupnp_controlpoint_ipchanged(mUpnpControlPoint *ctrlPoint) { mUpnpNetworkInterfaceList *current, *added, *removed; mUpnpNetworkInterface *netIf; mUpnpDevice *dev, *tmp; mUpnpSSDPPacket *ssdpPkt; char *address; mupnp_log_debug_l4("Entering...\n"); current = mupnp_net_interfacelist_new(); added = mupnp_net_interfacelist_new(); removed = mupnp_net_interfacelist_new(); if (current == NULL || added == NULL || removed == NULL) { if (current != NULL) mupnp_net_interfacelist_delete(current); if (added != NULL) mupnp_net_interfacelist_delete(added); if (removed != NULL) mupnp_net_interfacelist_delete(removed); return false; } /* Get Interface changes */ mupnp_net_gethostinterfaces(current); mupnp_net_interfacelist_getchanges(ctrlPoint->ifCache, current, added, removed); /* Remove all devices registered through old interface */ for (netIf = mupnp_net_interfacelist_gets(removed); netIf != NULL; netIf = mupnp_net_interface_next(netIf)) { mupnp_controlpoint_lock(ctrlPoint); tmp = mupnp_controlpoint_getdevices(ctrlPoint); while (tmp != NULL) { dev = tmp; tmp = mupnp_device_next(dev); ssdpPkt = mupnp_device_getssdppacket(dev); address = mupnp_ssdp_packet_getlocaladdress(ssdpPkt); if (address != NULL && mupnp_strcmp(address, mupnp_net_interface_getaddress(netIf)) == 0) { /* This device has been received from the removed interface, so it does not exist */ mupnp_controlpoint_unlock(ctrlPoint); mupnp_controlpoint_removedevicebyssdppacket(ctrlPoint, ssdpPkt); mupnp_controlpoint_lock(ctrlPoint); address = NULL; dev = NULL; ssdpPkt = NULL; } } mupnp_controlpoint_unlock(ctrlPoint); } /* Launch new M-SEARCH */ mupnp_controlpoint_search(ctrlPoint, MUPNP_ST_ROOT_DEVICE); /**** Cache current interfaces ****/ mupnp_net_gethostinterfaces(ctrlPoint->ifCache); mupnp_net_interfacelist_delete(current); mupnp_net_interfacelist_delete(added); mupnp_net_interfacelist_delete(removed); mupnp_log_debug_l4("Leaving...\n"); return true; }
mUpnpAvServer *mupnp_upnpav_dms_new() { mUpnpAvServer *dms; dms = (mUpnpAvServer *)malloc(sizeof(mUpnpAvServer)); dms->dev = mupnp_device_new(); if (!dms->dev) { free(dms); return NULL; } if (mupnp_device_parsedescription(dms->dev, CG_UPNPAV_DMS_DEVICE_DESCRIPTION, mupnp_strlen(CG_UPNPAV_DMS_DEVICE_DESCRIPTION)) == false) { mupnp_device_delete(dms->dev); free(dms); return NULL; } if (mupnp_upnpav_dms_conmgr_init(dms) == false) { mupnp_device_delete(dms->dev); free(dms); return NULL; } if (mupnp_upnpav_dms_condir_init(dms) == false) { mupnp_device_delete(dms->dev); free(dms); return NULL; } if (mupnp_upnpav_dms_medrec_init(dms) == false) { mupnp_device_delete(dms->dev); free(dms); return NULL; } dms->rootContent = mupnp_upnpav_content_new(); mupnp_upnpav_content_settype(dms->rootContent, CG_UPNPAV_CONTENT_CONTAINER); mupnp_upnpav_content_settitle(dms->rootContent, CG_UPNPAV_ROOT_CONTENT_TITLE); mupnp_upnpav_content_setid(dms->rootContent, CG_UPNPAV_ROOT_CONTENT_ID); mupnp_upnpav_content_setparentid(dms->rootContent, CG_UPNPAV_ROOT_CONTENT_PARENTID); if (!dms->rootContent) { mupnp_upnpav_dms_delete(dms); return NULL; } dms->mutex = mupnp_mutex_new(); if (!dms->mutex) { mupnp_upnpav_dms_delete(dms); return NULL; } dms->networkInterfaceList = mupnp_net_interfacelist_new(); if (!dms->networkInterfaceList) { mupnp_upnpav_dms_delete(dms); return NULL; } mupnp_device_setactionlistener(dms->dev, mupnp_upnpav_dms_actionreceived); mupnp_device_setquerylistener(dms->dev, mupnp_upnpav_dms_queryreceived); mupnp_device_sethttplistener(dms->dev, mupnp_upnpav_dms_device_httprequestrecieved); mupnp_upnpav_dms_setactionlistener(dms, NULL); mupnp_upnpav_dms_setquerylistener(dms, NULL); mupnp_upnpav_dms_sethttplistener(dms, NULL); mupnp_device_setuserdata(dms->dev, dms); mupnp_device_updateudn(dms->dev); dms->protocolInfoList = mupnp_upnpav_protocolinfolist_new(); return dms; }