55#include <umock/sys_socket.hpp>
56#include <umock/stdlib.hpp>
57#include <umock/pupnp_miniserver.hpp>
58#include <umock/pupnp_ssdp.hpp>
94#ifdef COMPA_HAVE_WEBSERVER
119 TRACE(
"Executing active_connection_cmp()");
124 return (conn1->socket == conn2->socket);
131 TRACE(
"Executing add_active_connection()");
144 conn->connect_time = time(NULL);
150 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
151 "Added active connection: socket %d\n", sock);
159 TRACE(
"Executing remove_active_connection()");
167 search_conn.socket = sock;
168 search_conn.connect_time = 0;
174 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
175 "Removed active connection: socket %d\n", sock);
184 TRACE(
"Executing shutdown_all_active_connections()");
191 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
192 "Shutting down all active socket connections\n");
200 if (conn && conn->socket != INVALID_SOCKET) {
201 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
202 "Force shutting down socket %d\n", conn->socket);
203 shutdown(conn->socket, SD_BOTH);
215 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
216 "Shutdown %d active socket connections and clean\n", count);
226 size_t a_host_port_len
228 TRACE(
"Executing host_header_is_numeric()");
229 if (a_host_port_len == 0 || strncmp(a_host_port,
"[::]", 4) == 0 ||
230 strncmp(a_host_port,
"0.0.0.0", 7) == 0)
235 saddrObj = std::string(a_host_port, a_host_port_len);
236 }
catch (
const std::exception& e) {
237 UPnPsdk_LOGCATCH(
"MSG1049") << e.what() <<
"\n";
256 TRACE(
"Executing getNumericHostRedirection()")
262 memcpy(a_host_port, sa.
netaddrp().c_str(), a_hp_size);
265 }
catch (
const std::exception& ex) {
266 UPnPsdk_LOGCATCH(
"MSG1093")
"catched next line...\n" << ex.what();
295 case SOAPMETHOD_POST:
296 case HTTPMETHOD_MPOST:
298 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
299 "miniserver %d: got SOAP msg\n", a_info->
socket);
302 case HTTPMETHOD_NOTIFY:
303 case HTTPMETHOD_SUBSCRIBE:
304 case HTTPMETHOD_UNSUBSCRIBE:
306 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
307 "miniserver %d: got GENA msg\n", a_info->
socket);
311 case HTTPMETHOD_POST:
312 case HTTPMETHOD_HEAD:
313 case HTTPMETHOD_SIMPLEGET:
317 UPnPsdk_LOGINFO(
"MSG1107")
"miniserver socket="
318 << a_info->
socket <<
": got WEB server msg.\n";
324 rc = HTTP_INTERNAL_SERVER_ERROR;
327 request = &a_hparser->
msg;
330 UPnPsdk_LOGINFO(
"MSG1113")
"Redirect host_port=\"" << host_port
338 min_size = header.
length < ((
sizeof host_port) - 1)
340 : (
sizeof host_port) - 1;
341 memcpy(host_port, header.
buf, min_size);
342 host_port[min_size] = 0;
343 if (host_validate_callback) {
344 rc = host_validate_callback(host_port, cookie);
351 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
352 "Possible DNS Rebind attack prevented.\n");
356 static const char* redir_fmt =
"HTTP/1.1 307 Temporary Redirect\r\n"
357 "Location: http://%s\r\n\r\n";
364 snprintf(redir_str,
NAME_SIZE, redir_fmt, host_port);
372 callback(a_hparser, request, a_info);
385 TRACE(
"Executing free_handle_request_arg()")
402 TRACE(
"Executing handle_request()")
403 int http_major_version{1};
404 int http_minor_version{1};
407 SOCKET sock = request_in->
sock;
416 UPnPsdk_LOGINFO(
"MSG1027")
"UDevice socket="
417 << sock <<
": READING request on local=\"" << local_saObj.
netaddrp()
418 <<
"\" from control point remote=\"" << remote_saObj.
netaddrp()
443 UPnPsdk_LOGINFO(
"MSG1106")
"miniserver socket=" << sock
444 <<
": PROCESSING...\n";
449 if (http_error_code > 0) {
461 UPnPsdk_LOGINFO(
"MSG1058")
"miniserver socket(" << sock <<
"); COMPLETE.\n";
473 TRACE(
"Executing schedule_request_job()")
479 UPnPsdk_LOGINFO(
"MSG1042")
"Schedule UDevice to accept incomming "
480 "request with socket("
481 << a_sock <<
") local=\"" << local_saObj.
netaddrp()
482 <<
"\" remote=\"" << clientAddr.
netaddrp() <<
"\".\n";
488 if (request ==
nullptr) {
489 UPnPsdk_LOGCRIT(
"MSG1024")
"Socket(" << a_sock <<
"): out of memory.\n";
494 request->sock = a_sock;
495 memcpy(&request->foreign_sockaddr, &clientAddr.
ss,
496 sizeof(request->foreign_sockaddr));
505 UPnPsdk_LOGERR(
"MSG1025")
"Socket("
506 << a_sock <<
"): failed to add job to miniserver threadpool.\n";
537 TRACE(
"Executing fdset_if_valid(): check sockfd=" + std::to_string(a_sock))
538 if (a_sock == INVALID_SOCKET)
542 if (a_sock < 3 || a_sock >= FD_SETSIZE) {
543 UPnPsdk_LOGERR(
"MSG1005")
544 << (a_sock < 0 ?
"Invalid" :
"Prohibited") <<
" socket " << a_sock
545 <<
" not set to be monitored by ::select()"
546 << (a_sock >= 3 ?
" because it violates FD_SETSIZE.\n" :
".\n");
555 FD_SET(a_sock, a_set);
558 UPnPsdk_LOGINFO(
"MSG1002")
"Unbound socket "
559 << a_sock <<
" not set to be monitored by ::select().\n";
561 }
catch (
const std::exception& e) {
563 std::cerr << e.what();
564 UPnPsdk_LOGCATCH(
"MSG1009")
"Invalid socket "
565 << a_sock <<
" not set to be monitored by ::select().\n";
582 [[maybe_unused]] SOCKET listen_sock,
584 [[maybe_unused]] fd_set& set) {
585#ifndef COMPA_HAVE_WEBSERVER
588 TRACE(
"Executing web_server_accept()")
589 if (listen_sock == INVALID_SOCKET || !FD_ISSET(listen_sock, &set)) {
590 UPnPsdk_LOGINFO(
"MSG1012")
"Socket("
591 << listen_sock <<
") invalid or not in file descriptor set.\n";
596 socklen_t ctrlpntLen =
sizeof(ctrlpnt_saObj.
ss);
600 umock::sys_socket_h.accept(listen_sock, &ctrlpnt_saObj.
sa, &ctrlpntLen);
601 if (conn_sock == INVALID_SOCKET) {
602 UPnPsdk_LOGERR(
"MSG1022")
"Error in ::accept(): "
603 << std::strerror(errno) <<
".\n";
610 listen_sockObj.
load();
619 UPnPsdk_LOGINFO(
"MSG1023")
"Listening socket("
620 << listen_sock <<
") on \"" << listen_saObj.
netaddrp()
621 <<
"\" accept connection socket(" << conn_sock <<
") local=\""
622 << conn_saObj.
netaddrp() <<
"\" to remote=\""
623 << ctrlpnt_saObj.
netaddrp() <<
"\".\n";
640 TRACE(
"Executing ssdp_read()")
641 if (*rsock == INVALID_SOCKET || !FD_ISSET(*rsock, set))
644#if defined(COMPA_HAVE_CTRLPT_SSDP) || defined(COMPA_HAVE_DEVICE_SSDP)
646 UpnpPrintf(UPNP_ERROR, MSERV, __FILE__, __LINE__,
647 "miniserver: Error in readFromSSDPSocket(%d): "
651 *rsock = INVALID_SOCKET;
655 *rsock = INVALID_SOCKET;
677 TRACE(
"Executing receive_from_stopSock()")
678 constexpr char shutdown_str[]{
"ShutDown"};
680 if (!FD_ISSET(ssock, set))
684 socklen_t clientLen{
sizeof(clientAddr)};
688 char receiveBuf[
sizeof(shutdown_str) + 1]{};
689 char buf_ntop[INET6_ADDRSTRLEN];
692 SSIZEP_T byteReceived = umock::sys_socket_h.recvfrom(
693 ssock, receiveBuf,
sizeof(shutdown_str), 0, &clientAddr.sa, &clientLen);
694 if (byteReceived == SOCKET_ERROR ||
695 inet_ntop(AF_INET, &clientAddr.sin.sin_addr, buf_ntop,
696 sizeof(buf_ntop)) ==
nullptr) {
697 UPnPsdk_LOGCRIT(
"MSG1038")
"Failed to receive data from socket "
698 << ssock <<
". Stop miniserver.\n";
703 if (clientAddr.sin.sin_addr.s_addr != htonl(2130706433) ||
704 strcmp(receiveBuf, shutdown_str) != 0)
706 char nullstr[]{
"\\0"};
707 if (byteReceived == 0 || receiveBuf[byteReceived - 1] !=
'\0')
709 UPnPsdk_LOGERR(
"MSG1039")
"Received \""
710 << receiveBuf << nullstr <<
"\" from " << buf_ntop <<
":"
711 << ntohs(clientAddr.sin.sin_port)
712 <<
", must be \"ShutDown\\0\" from 127.0.0.1:*. Don't "
713 "stopping miniserver.\n";
717 UPnPsdk_LOGINFO(
"MSG1040")
"On socket "
718 << ssock <<
" received ordinary datagram \"" << receiveBuf
719 <<
"\\0\" from " << buf_ntop <<
":" << ntohs(clientAddr.sin.sin_port)
720 <<
". Stop miniserver.\n";
740 UPnPsdk_LOGINFO(
"MSG1085")
"Executing...\n";
742#ifdef COMPA_HAVE_WEBSERVER
747 if (miniSock->pSockLlaObj !=
nullptr) {
748 sockLlaObj = std::move(*miniSock->pSockLlaObj);
749 miniSock->pSockLlaObj = &sockLlaObj;
752 if (miniSock->pSockGuaObj !=
nullptr) {
753 sockGuaObj = std::move(*miniSock->pSockGuaObj);
754 miniSock->pSockGuaObj = &sockGuaObj;
757 if (miniSock->pSockIp4Obj !=
nullptr) {
758 sockIp4Obj = std::move(*miniSock->pSockIp4Obj);
759 miniSock->pSockIp4Obj = &sockIp4Obj;
771 SOCKET maxMiniSock = 0;
789 std::max(maxMiniSock, miniSock->
ssdpSock4 == INVALID_SOCKET
793 std::max(maxMiniSock, miniSock->
ssdpSock6 == INVALID_SOCKET
800#ifdef COMPA_HAVE_CTRLPT_SSDP
802 std::max(maxMiniSock, miniSock->
ssdpReqSock4 == INVALID_SOCKET
806 std::max(maxMiniSock, miniSock->
ssdpReqSock6 == INVALID_SOCKET
825#ifdef COMPA_HAVE_CTRLPT_SSDP
831 int ret = umock::sys_socket_h.select(
static_cast<int>(maxMiniSock),
832 &rdSet, NULL, &expSet, NULL);
834 if (ret == SOCKET_ERROR) {
835 if (errno == EINTR) {
839 if (errno == EBADF) {
851 UPnPsdk_LOGCRIT(
"MSG1021")
"Error in ::select(): "
852 << std::strerror(errno) <<
".\n";
862 [[maybe_unused]]
int ret1 =
864 [[maybe_unused]]
int ret2 =
866 [[maybe_unused]]
int ret3 =
868#ifdef COMPA_HAVE_CTRLPT_SSDP
882#ifdef COMPA_HAVE_WEBSERVER
895#ifdef COMPA_HAVE_CTRLPT_SSDP
900 umock::stdlib_h.free(miniSock);
903 UPnPsdk_LOGINFO(
"MSG1060")
"Finished.\n";
908 umock::pupnp_miniserver.RunMiniServer(miniSock);
924 TRACE(
"Executing get_port(), calls system ::getsockname()")
926 socklen_t len(
sizeof sockinfo);
928 if (umock::sys_socket_h.getsockname(sockfd, &sockinfo.sa, &len) == -1)
932 switch (sockinfo.ss.ss_family) {
935 *port = ntohs(sockinfo.sin6.sin6_port);
941 UPnPsdk_LOGINFO(
"MSG1063")
"sockfd=" << sockfd <<
", port=" << *port
947#ifdef COMPA_HAVE_WEBSERVER
975 in_port_t listen_port4,
979 in_port_t listen_port6,
983 in_port_t listen_port6UlaGua) {
984 UPnPsdk_LOGINFO(
"MSG1109")
"Executing with listen_port4="
985 << listen_port4 <<
", listen_port6=" << listen_port6
986 <<
", listen_port6UlaGua=" << listen_port6UlaGua <<
".\n";
990 if (out->pSockLlaObj !=
nullptr &&
gIF_IPV6[0] !=
'\0') {
993 if (::strncmp(
gIF_IPV6,
"::1", 3) == 0)
996 saObj =
'[' + std::string(
gIF_IPV6) +
997 "]:" + std::to_string(listen_port6);
999 saObj =
'[' + std::string(
gIF_IPV6) +
'%' +
1001 "]:" + std::to_string(listen_port6);
1002 out->pSockLlaObj->
bind(SOCK_STREAM, &saObj, AI_PASSIVE);
1003 out->pSockLlaObj->
listen();
1008 }
catch (
const std::exception& ex) {
1009 UPnPsdk_LOGCATCH(
"MSG1110")
"gIF_IPV6=\""
1010 <<
gIF_IPV6 <<
"\", catched next line...\n"
1023 "]:" + std::to_string(listen_port6UlaGua);
1024 out->pSockGuaObj->
bind(SOCK_STREAM, &saObj, AI_PASSIVE);
1025 out->pSockGuaObj->
listen();
1030 }
catch (
const std::exception& ex) {
1031 UPnPsdk_LOGCATCH(
"MSG1117")
"gIF_IPV6_ULA_GUA=\""
1037 if (out->pSockIp4Obj !=
nullptr &&
gIF_IPV4[0] !=
'\0') {
1040 saObj = std::string(
gIF_IPV4) +
':' + std::to_string(listen_port4);
1041 out->pSockIp4Obj->
bind(SOCK_STREAM, &saObj, AI_PASSIVE);
1042 out->pSockIp4Obj->
listen();
1047 }
catch (
const std::exception& ex) {
1048 UPnPsdk_LOGCATCH(
"MSG1114")
"gIF_IPV4=\""
1049 <<
gIF_IPV4 <<
"\", catched next line...\n"
1055 UPnPsdk_LOGERR(
"MSG1065")
"No valid IP address on a local network "
1056 "adapter found for listening.\n";
1080 TRACE(
"Executing get_miniserver_stopsock()");
1081 sockaddr_in stop_sockaddr;
1084 SOCKET miniServerStopSock =
1085 umock::sys_socket_h.socket(AF_INET, SOCK_DGRAM, 0);
1086 if (miniServerStopSock == INVALID_SOCKET) {
1088 UPnPsdk_LOGCRIT(
"MSG1094")
"Error in socket(): "
1093 memset(&stop_sockaddr, 0,
sizeof(stop_sockaddr));
1094 stop_sockaddr.sin_family = AF_INET;
1095 inet_pton(AF_INET,
"127.0.0.1", &stop_sockaddr.sin_addr);
1096 int ret = umock::sys_socket_h.bind(
1097 miniServerStopSock,
reinterpret_cast<sockaddr*
>(&stop_sockaddr),
1098 sizeof(stop_sockaddr));
1099 if (ret == SOCKET_ERROR) {
1101 UPnPsdk_LOGCRIT(
"MSG1095")
"Error in binding localhost: "
1114 UPnPsdk_LOGINFO(
"MSG1053")
"Bound stop socket="
1127 TRACE(
"Executing InitMiniServerSockArray()");
1139#ifdef COMPA_HAVE_CTRLPT_SSDP
1143#ifdef COMPA_HAVE_WEBSERVER
1144 miniSocket->pSockLlaObj =
nullptr;
1145 miniSocket->pSockGuaObj =
nullptr;
1146 miniSocket->pSockIp4Obj =
nullptr;
1154#ifdef COMPA_HAVE_DEVICE_SOAP
1156 TRACE(
"Executing SetSoapCallback()");
1161#ifdef COMPA_HAVE_DEVICE_GENA
1163 TRACE(
"Executing SetGenaCallback()");
1169 [[maybe_unused]] in_port_t* listen_port6,
1170 [[maybe_unused]] in_port_t* listen_port6UlaGua) {
1171 UPnPsdk_LOGINFO(
"MSG1068")
"Executing...\n";
1172 constexpr int max_count{10000};
1177 memset(&job, 0,
sizeof(job));
1181 UPnPsdk_LOGERR(
"MSG1087")
"Cannot start. Miniserver is running.\n";
1191#ifdef COMPA_HAVE_WEBSERVER
1195 miniSocket->pSockLlaObj = &sockLlaObj;
1197 miniSocket->pSockGuaObj = &sockGuaObj;
1199 miniSocket->pSockIp4Obj = &sockIp4Obj;
1203 *listen_port6UlaGua);
1219#if defined(COMPA_HAVE_CTRLPT_SSDP) || defined(COMPA_HAVE_DEVICE_SSDP)
1221 ret_code = umock::pupnp_ssdp.get_ssdp_sockets(miniSocket);
1236 if (ret_code != 0) {
1244#ifdef COMPA_HAVE_CTRLPT_SSDP
1255 std::this_thread::sleep_for(std::chrono::milliseconds(50));
1258 if (count >= max_count) {
1267#ifdef COMPA_HAVE_CTRLPT_SSDP
1273#ifdef COMPA_HAVE_WEBSERVER
1283 UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
1284 "Inside StopMiniServer()\n");
1286 socklen_t socklen =
sizeof(
struct sockaddr_in);
1288 sockaddr_in ssdpAddr;
1289 char buf[256] =
"ShutDown";
1291 size_t bufLen = strlen(buf);
1300 sock = umock::sys_socket_h.socket(AF_INET, SOCK_DGRAM, 0);
1301 if (sock == INVALID_SOCKET) {
1302 UpnpPrintf(UPNP_ERROR, SSDP, __FILE__, __LINE__,
1303 "SSDP_SERVER: StopSSDPServer: Error in socket() %s\n",
1304 std::strerror(errno));
1308 ssdpAddr.sin_family = (sa_family_t)AF_INET;
1309 inet_pton(AF_INET,
"127.0.0.1", &ssdpAddr.sin_addr);
1311 umock::sys_socket_h.sendto(sock, buf, (SIZEP_T)bufLen, 0,
1312 reinterpret_cast<sockaddr*
>(&ssdpAddr),
1314 std::this_thread::sleep_for(std::chrono::milliseconds(1));
1318 std::this_thread::sleep_for(std::chrono::seconds(1));
#define UPNP_E_NO_WEB_SERVER
The operation completed successfully.
http_message_t msg
entire raw message
http_method_t method
Http method of an outgoing request.
int major_version
Http major version.
#define HDR_HOST
Type of a HTTP header.
int minor_version
Http minor version.
Structure of an HTTP parser object.
Structure of an HTTP message.
int ListDestroy(LinkedList *list, int freeItem)
Removes all memory associated with list nodes. Does not free LinkedList *list.
void * ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)
Removes a node from the list. The memory for the node is freed.
ListNode * ListNext(LinkedList *list, ListNode *node)
Returns the next item in the list.
ListNode * ListHead(LinkedList *list)
Returns the head of the list.
ListNode * ListAddTail(LinkedList *list, void *item)
Adds a node to the tail of the list. Node gets added immediately before list.tail.
ListNode * ListFind(LinkedList *list, ListNode *start, void *item)
Finds the specified item in the list.
int ListInit(LinkedList *list, cmp_routine cmp_func, free_function free_func)
Initializes LinkedList. Must be called first and only once for List.
Linked list node. Stores generic item and pointers to next and prev.
Linked list (no protection).
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
Adds a job to the thread pool.
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func)
Sets the jobs free function.
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority)
Sets the priority of the threadpool job.
int TPJobInit(ThreadPoolJob *job, UPnPsdk::start_routine func, void *arg)
Initializes thread pool job.
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
Adds a persistent job to the thread pool.
void(* free_routine)(void *arg)
Class for portable handling of network socket errors.
void catch_error()
Catch error for later use.
std::string error_str() const
Get human readable error description of the catched error.
Get information from a raw network socket file descriptor.
bool local_saddr(SSockaddr *a_saddr=nullptr) const
Get the local socket address the socket is bound to.
void load()
Load the raw socket file descriptor specified with the constructor into the object.
Manage all aspects of a network socket.
void listen()
Set socket to listen.
void bind(const int a_socktype, const SSockaddr *const a_saddr=nullptr, const int a_flags=0)
Bind socket to an ip address of a local network adapter.
int readFromSSDPSocket(SOCKET socket)
This function reads the data from the ssdp socket.
int(* WebCallback_HostValidate)(const char *hostname, void *cookie)
Callback for validating HTTP requests HOST header values.
Helpful union of the different socket address structures.
http_header_t * httpmsg_find_hdr(http_message_t *msg, int header_name_id, memptr *value)
Finds header from a list, with the given 'name_id'.
void httpmsg_destroy(http_message_t *msg)
Free memory allocated for the http message.
int http_SendMessage(SOCKINFO *info, int *TimeOut, const char *fmt,...)
Sends a message to the destination based on the format parameter.
int http_SendStatusResponse(SOCKINFO *info, int http_status_code, int request_major_version, int request_minor_version)
Generate a response message for the status query and send the status response.
int http_RecvMessage(SOCKINFO *info, http_parser_t *parser, http_method_t request_method, int *timeout_secs, int *http_error_code)
Get the data on the socket and take actions based on the read data to modify the parser objects buffe...
Performs HTTP read and write messages.
#define HTTP_DEFAULT_TIMEOUT
void membuffer_destroy(membuffer *m)
Free's memory allocated for membuffer* m.
void membuffer_init(membuffer *m)
Wrapper to membuffer_initialize().
int membuffer_append_str(membuffer *m, const char *c_str)
Invokes function to appends data from a constant string to the buffer.
size_t length
length of buffer without terminating null byte (read-only).
char * buf
mem buffer; must not write beyond buf[length-1] (read/write).
size_t length
length of memory without terminating '\0' (read-only).
char * buf
start of memory (read/write).
pointer to a chunk of memory.
Maintains a block of dynamically allocated memory.
#define UPNP_E_SOCKET_ERROR
Generic socket error code for conditions not covered by other error codes.
#define UPNP_E_SOCKET_BIND
The SDK had a problem binding a socket to a network interface.
#define UPNP_E_BAD_HTTPMSG
The HTTP message contains invalid message headers.
#define UPNP_E_SUCCESS
The operation completed successfully.
#define UPNP_E_OUTOF_SOCKET
The SDK cannot create any more sockets.
#define UPNP_E_OUTOF_MEMORY
Not enough resources are currently available to complete the operation.
#define UPNP_E_SOCKET_ACCEPT
The SDK had a problem accepting a network connection.
#define UPNP_E_INTERNAL_ERROR
Generic error code for internal conditions not covered by other error codes.
void SetSoapCallback(MiniServerCallback callback)
Set SOAP Callback.
int StartMiniServer(in_port_t *listen_port4, in_port_t *listen_port6, in_port_t *listen_port6UlaGua)
Initialize the sockets functionality for the Miniserver.
int StopMiniServer()
Stop and Shutdown the MiniServer and free socket resources.
void SetGenaCallback(MiniServerCallback callback)
Set GENA Callback.
Manage "Step 0: Addressing" of the UPnP+™ specification.
in_port_t miniServerPort6
Corresponding port to miniServerSock6.
in_port_t miniServerPort6UlaGua
Corresponding port to miniServerSock6UlaGua.
SOCKET ssdpSock4
IPv4 SSDP datagram Socket for incoming advertisments and search requests.
void(* MiniServerCallback)(http_parser_t *parser, http_message_t *request, SOCKINFO *info)
For a miniserver callback function.
SOCKET miniServerSock6UlaGua
IPv6 ULA or GUA Socket for listening for miniserver requests.
in_port_t stopPort
Corresponding port to miniServerStopSock. This is set with miniStopSockPort but never used.
SOCKET miniServerSock4
IPv4 socket for listening for miniserver requests.
in_port_t miniServerPort4
Corresponding port to miniServerSock4.
MiniServerCallback gGetCallback
HTTP server callback.
SOCKET ssdpReqSock6
IPv6 SSDP socket for sending search requests and receiving search replies.
SOCKET ssdpReqSock4
IPv4 SSDP socket for sending search requests and receiving search replies.
SOCKET miniServerStopSock
Datagram Socket for stopping miniserver.
SOCKET ssdpSock6
IPv6 LLA SSDP Socket for incoming advertisments and search requests.
SOCKET miniServerSock6
IPv6 LLA Socket for listening for miniserver requests.
SOCKET ssdpSock6UlaGua
IPv6 ULA or GUA SSDP Socket for incoming advertisments and search requests.
Provides sockets for all network communications.
UPnPsdk_EXTERN bool g_dbug
Switch to enable verbose (debug) output.
void ssdp_read(SOCKET *rsock, fd_set *set)
Read data from the SSDP socket.
int host_header_is_numeric(char *a_host_port, size_t a_host_port_len)
Check if a network address is numeric.
void schedule_request_job(SOCKET a_sock, UPnPsdk::SSockaddr &clientAddr)
Initilize the thread pool to handle an incomming request, sets priority for the job and adds the job ...
static void remove_active_connection(SOCKET sock)
Remove a socket from the active connections list.
int get_miniserver_stopsock(MiniServerSockArray *out)
Creates the miniserver STOP socket, usable to listen for stopping the miniserver.
static pthread_mutex_t gActiveConnectionsMutex
void shutdown_all_active_connections(void)
Shutdown all active socket connections.
void RunMiniServer(MiniServerSockArray *miniSock)
Run the miniserver.
MiniServerCallback gSoapCallback
SOAP callback.
int web_server_accept(SOCKET listen_sock, fd_set &set)
Accept requested connection from a remote control point and run it in a new thread.
void InitMiniServerSockArray(MiniServerSockArray *miniSocket)
Initialize a miniserver Socket Array.
static int gActiveConnectionsInitialized
void free_handle_request_arg(void *args)
Free memory assigned for handling request and unitialize socket functionality.
in_port_t miniStopSockPort
Port of the stop socket.
int getNumericHostRedirection(SOCKET a_socket, char *a_host_port, size_t a_hp_size)
Returns the ip address with port as text that is bound to a socket.
MiniServerCallback gGenaCallback
GENA callback.
int receive_from_stopSock(SOCKET ssock, fd_set *set)
Check if we have received a packet that shall stop the miniserver.
int get_miniserver_sockets(MiniServerSockArray *out, in_port_t listen_port4, in_port_t listen_port6, in_port_t listen_port6UlaGua)
Create STREAM sockets, binds to local network interfaces and listens for incoming connections.
void RunMiniServer_f(MiniServerSockArray *miniSock)
void fdset_if_valid(SOCKET a_sock, fd_set *a_set)
Add a socket file descriptor to an 'fd_set' structure as needed for ::select().
sockaddr_storage foreign_sockaddr
Socket address of the remote control point.
MiniServerState
miniserver state
@ MSERV_RUNNING
miniserver is running.
@ MSERV_IDLE
miniserver is idle.
@ MSERV_STOPPING
miniserver is running to stop.
void handle_request(void *args)
Receive the request and dispatch it for handling.
static void add_active_connection(SOCKET sock)
Add a socket to the active connections list.
static LinkedList gActiveConnections
SOCKET sock
Connection socket file descriptor.
int dispatch_request(SOCKINFO *a_info, http_parser_t *a_hparser)
Based on the type of message, appropriate callback is issued.
MiniServerState gMServState
miniserver state
static int active_connection_cmp(void *first, void *second)
Compare function for active connections, return true if equal (found)
int get_port(SOCKET sockfd, uint16_t *port)
Returns port to which socket, sockfd, is bound.
miniserver received request message.
int sock_destroy(SOCKINFO *info, int ShutdownMethod)
Shutsdown the socket using the ShutdownMethod to indicate whether sends and receives on the socket wi...
int sock_init_with_ip(SOCKINFO *info, SOCKET sockfd, sockaddr *foreign_sockaddr)
Calls the sock_init function and assigns the passed in IP address and port to the IP address and port...
SOCKET socket
Handle/descriptor to a socket.
int sock_close(SOCKET sock)
Closes the socket if it is different from -1.
Additional socket information for connections and ssl.
Manage "Step 1: Discovery" of the UPnP+™ specification with SSDP.
Trivial ::sockaddr structures enhanced with methods.
const std::string netaddrp() noexcept
Get the assosiated netaddress with port.
sockaddr & sa
Reference to sockaddr struct.
in_port_t port() const
Get the numeric port.
sockaddr_storage & ss
Reference to sockaddr_storage struct.
WebCallback_HostValidate gWebCallback_HostValidate
webCallback for HOST validation.
char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN]
IPv6 GUA buffer to contain interface IPv6 global-unicast address.
int gAllowLiteralHostRedirection
Allow literal host names redirection to numeric host names.
void * gWebCallback_HostValidateCookie
Cookie to the webCallback for HOST validation.
char gIF_IPV4[INET_ADDRSTRLEN]
IPv4 buffer to contain interface address. (extern'ed in upnp.h)
unsigned gIF_INDEX
Index/scope-id from the used network interface.
ThreadPool gMiniServerThreadPool
Mini server thread pool.
char gIF_IPV6[INET6_ADDRSTRLEN]
IPv6 LLA buffer to contain interface address. (extern'ed in upnp.h)
Inititalize the compatible library before it can be used.
UPnPsdk_VIS void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module, const char *DbgFileName, int DbgLineNo, const char *FmtStr,...)
Prints the debug statement.