Skip to content

Commit

Permalink
Merge branch 'master' of https://framagit.org/medoc92/npupnp
Browse files Browse the repository at this point in the history
  • Loading branch information
medoc92 committed Jan 1, 2024
2 parents 2eca6d5 + e56ccd6 commit 7596cf8
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 16 deletions.
1 change: 1 addition & 0 deletions inc/netif.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ class EXPORT_SPEC Interfaces {
/** @brief Return the Interfaces singleton after possibly building
* it by querying the system */
static Interfaces *theInterfaces();
static void cleanup();

/** @brief Read the state from the system again */
bool refresh();
Expand Down
1 change: 1 addition & 0 deletions src/api/upnpapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ EXPORT_SPEC int UpnpFinish()
UpnpRemoveAllVirtualDirs();
UpnpSdkInit = 0;
UpnpCloseLog();
NetIF::Interfaces::cleanup();

return UPNP_E_SUCCESS;
}
Expand Down
25 changes: 15 additions & 10 deletions src/dispatcher/miniserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,18 @@ int StartMiniServer(uint16_t *listen_port4, uint16_t *listen_port6)
goto out;
}

/* Check what port we should listen on */
port = available_port(static_cast<int>(*listen_port4));
if (port < 0) {
UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
"miniserver: available_port() failed !\n");
return port;
}
*listen_port4 = port;
*listen_port6 = port;

/* SSDP socket for discovery/advertising. */
ret_code = get_ssdp_sockets(miniSocket);
ret_code = get_ssdp_sockets(miniSocket, port);
if (ret_code != UPNP_E_SUCCESS) {
UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
"miniserver: get_ssdp_sockets() failed\n");
Expand All @@ -769,15 +779,6 @@ int StartMiniServer(uint16_t *listen_port4, uint16_t *listen_port6)
}

#ifdef INTERNAL_WEB_SERVER
port = available_port(static_cast<int>(*listen_port4));
if (port < 0) {
UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
"miniserver: available_port() failed !\n");
return port;
}
*listen_port4 = port;
*listen_port6 = port;

mhdflags = MHD_USE_THREAD_PER_CONNECTION | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_DEBUG;

#ifdef UPNP_ENABLE_IPV6
Expand Down Expand Up @@ -825,6 +826,10 @@ int StopMiniServer()
return 0;
}

#ifdef INTERNAL_WEB_SERVER
MHD_stop_daemon(mhd);
#endif

sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
posix_strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
Expand Down
5 changes: 4 additions & 1 deletion src/inc/ssdplib.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,10 @@ void readFromSSDPSocket(
*/
int get_ssdp_sockets(
/* [out] Array of SSDP sockets. */
MiniServerSockArray *out);
MiniServerSockArray *out,
/* [in] Port to listen on. -1 for default */
int port);



/*!
Expand Down
57 changes: 52 additions & 5 deletions src/ssdp/ssdp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ static int sock_make_no_blocking(SOCKET sock)
}

/* Create the SSDP IPv4 socket to be used by the control point. */
static int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock)
static int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock, int port)
{
char ttl = 2;
int ret = UPNP_E_SOCKET_ERROR;
Expand Down Expand Up @@ -439,6 +439,24 @@ static int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock)
}

sock_make_no_blocking(*ssdpReqSock);

if (port > 0)
{
struct sockaddr_storage ss = {};
auto ssdpAddr4 = reinterpret_cast<struct sockaddr_in *>(&ss);

ssdpAddr4->sin_family = static_cast<sa_family_t>(AF_INET);
ssdpAddr4->sin_addr.s_addr = htonl(INADDR_ANY);
ssdpAddr4->sin_port = htons(port);
ret = bind(*ssdpReqSock, reinterpret_cast<struct sockaddr *>(ssdpAddr4), sizeof(*ssdpAddr4));

if (ret == -1) {
errorcause = "bind(INADDR_ANY)";
ret = UPNP_E_SOCKET_BIND;
goto error_handler;
}
}

return UPNP_E_SUCCESS;

error_handler:
Expand Down Expand Up @@ -535,7 +553,7 @@ static int create_ssdp_sock_v6(bool isulagua, SOCKET *ssdpSock)

#ifdef INCLUDE_CLIENT_APIS
/* Create the SSDP IPv6 socket to be used by the control point. */
static int create_ssdp_sock_reqv6(SOCKET *ssdpReqSock)
static int create_ssdp_sock_reqv6(SOCKET *ssdpReqSock, int port)
{
#ifdef _WIN32
DWORD hops = 1;
Expand Down Expand Up @@ -567,6 +585,35 @@ static int create_ssdp_sock_reqv6(SOCKET *ssdpReqSock)

sock_make_no_blocking(*ssdpReqSock);

if (port > 0)
{
int onOff = 1;

// Set IPV6 socket to only bind to IPV6 (Linux Dual Stack)
ret = setsockopt(*ssdpReqSock, IPPROTO_IPV6, IPV6_V6ONLY,
reinterpret_cast<char *>(&onOff), sizeof(onOff));

if (ret == -1) {
errorcause = "setsockopt() IPV6_V6ONLY";
goto error_handler;
}

struct sockaddr_storage ss = {};
auto ssdpAddr6 = reinterpret_cast<struct sockaddr_in6 *>(&ss);

ssdpAddr6->sin6_family = static_cast<sa_family_t>(AF_INET6);
ssdpAddr6->sin6_addr = in6addr_any;
ssdpAddr6->sin6_scope_id = 0;
ssdpAddr6->sin6_port = htons(port);
ret = bind(*ssdpReqSock, reinterpret_cast<struct sockaddr *>(ssdpAddr6), sizeof(*ssdpAddr6));

if (ret == -1) {
errorcause = "bind(IN6ADDR_ANY)";
ret = UPNP_E_SOCKET_BIND;
goto error_handler;
}
}

return UPNP_E_SUCCESS;

error_handler:
Expand Down Expand Up @@ -602,7 +649,7 @@ static void closeSockets(MiniServerSockArray *out, int doclose)
maybeCLoseAndInvalidate(&out->ssdpSock6UlaGua, doclose);
}

int get_ssdp_sockets(MiniServerSockArray *out)
int get_ssdp_sockets(MiniServerSockArray *out, int port)
{
int retVal = UPNP_E_SOCKET_ERROR;
bool hasIPV4 = !apiFirstIPV4Str().empty();
Expand All @@ -613,7 +660,7 @@ int get_ssdp_sockets(MiniServerSockArray *out)
if (using_ipv6()) {
/* Create the IPv6 socket for SSDP REQUESTS */
if (hasIPV6) {
if ((retVal = create_ssdp_sock_reqv6(&out->ssdpReqSock6)) != UPNP_E_SUCCESS) {
if ((retVal = create_ssdp_sock_reqv6(&out->ssdpReqSock6, port)) != UPNP_E_SUCCESS) {
goto out;
}
/* For use by ssdp control point. */
Expand All @@ -623,7 +670,7 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif /* UPNP_ENABLE_IPV6 */
/* Create the IPv4 socket for SSDP REQUESTS */
if (hasIPV4) {
if ((retVal = create_ssdp_sock_reqv4(&out->ssdpReqSock4)) != UPNP_E_SUCCESS) {
if ((retVal = create_ssdp_sock_reqv4(&out->ssdpReqSock4, port)) != UPNP_E_SUCCESS) {
goto out;
}
/* For use by ssdp control point. */
Expand Down
6 changes: 6 additions & 0 deletions src/utils/netif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#endif

#include "netif.h"
#include "smallut.h"

#include <cstring>
#include <ostream>
Expand Down Expand Up @@ -780,6 +781,11 @@ Interfaces *Interfaces::theInterfaces()
return theInterfacesP;
}

void Interfaces::cleanup()
{
deleteZ(theInterfacesP);
}

std::ostream& Interfaces::print(std::ostream& out) {
const auto& ifs = theInterfaces()->m->interfaces;
for (const auto& entry : ifs) {
Expand Down

0 comments on commit 7596cf8

Please sign in to comment.