"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "minissdp.c" between
minidlna-1.2.1.tar.gz and minidlna-1.3.0.tar.gz

About: ReadyMedia (formerly known as MiniDLNA) is a simple media server software, with the aim of being fully compliant with DLNA/UPnP-AV clients.

minissdp.c  (minidlna-1.2.1):minissdp.c  (minidlna-1.3.0)
skipping to change at line 45 skipping to change at line 45
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include "event.h"
#include "minidlnapath.h" #include "minidlnapath.h"
#include "upnphttp.h" #include "upnphttp.h"
#include "upnpglobalvars.h" #include "upnpglobalvars.h"
#include "upnpreplyparse.h" #include "upnpreplyparse.h"
#include "getifaddr.h" #include "getifaddr.h"
#include "minissdp.h" #include "minissdp.h"
#include "codelength.h" #include "codelength.h"
#include "utils.h" #include "utils.h"
#include "log.h" #include "log.h"
skipping to change at line 147 skipping to change at line 148
} }
/* open the UDP socket used to send SSDP notifications to /* open the UDP socket used to send SSDP notifications to
* the multicast group reserved for them */ * the multicast group reserved for them */
int int
OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface) OpenAndConfSSDPNotifySocket(struct lan_addr_s *iface)
{ {
int s; int s;
unsigned char loopchar = 0; unsigned char loopchar = 0;
uint8_t ttl = 4; uint8_t ttl = 4;
#ifdef HAVE_STRUCT_IP_MREQN
struct ip_mreqn imr;
#else
struct in_addr mc_if; struct in_addr mc_if;
#endif
struct sockaddr_in sockname; struct sockaddr_in sockname;
s = socket(PF_INET, SOCK_DGRAM, 0); s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) if (s < 0)
{ {
DPRINTF(E_ERROR, L_SSDP, "socket(udp_notify): %s\n", strerror(err no)); DPRINTF(E_ERROR, L_SSDP, "socket(udp_notify): %s\n", strerror(err no));
return -1; return -1;
} }
mc_if.s_addr = iface->addr.s_addr;
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopchar, sizeo f(loopchar)) < 0) if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopchar, sizeo f(loopchar)) < 0)
{ {
DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_LOO P): %s\n", strerror(errno)); DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_LOO P): %s\n", strerror(errno));
close(s); close(s);
return -1; return -1;
} }
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char *)&mc_if, sizeof(mc_ #ifdef HAVE_STRUCT_IP_MREQN
if)) < 0) imr.imr_address = iface->addr;
imr.imr_ifindex = iface->ifindex;
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &imr, sizeof(imr)) < 0)
#else
mc_if = iface->addr;
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &mc_if, sizeof(mc_if)) < 0
)
#endif
{ {
DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_IF) : %s\n", strerror(errno)); DPRINTF(E_ERROR, L_SSDP, "setsockopt(udp_notify, IP_MULTICAST_IF) : %s\n", strerror(errno));
close(s); close(s);
return -1; return -1;
} }
setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
memset(&sockname, 0, sizeof(struct sockaddr_in)); memset(&sockname, 0, sizeof(struct sockaddr_in));
sockname.sin_family = AF_INET; sockname.sin_family = AF_INET;
skipping to change at line 207 skipping to change at line 217
uuidvalue, uuidvalue,
"upnp:rootdevice", "upnp:rootdevice",
"urn:schemas-upnp-org:device:MediaServer:", "urn:schemas-upnp-org:device:MediaServer:",
"urn:schemas-upnp-org:service:ContentDirectory:", "urn:schemas-upnp-org:service:ContentDirectory:",
"urn:schemas-upnp-org:service:ConnectionManager:", "urn:schemas-upnp-org:service:ConnectionManager:",
"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:", "urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:",
0 0
}; };
static void static void
_usleep(long usecs) _usleep(long min, long max)
{ {
struct timespec sleep_time; struct timespec sleep_time;
long usecs = min + rand() / (RAND_MAX / (max - min + 1) + 1);
sleep_time.tv_sec = 0; sleep_time.tv_sec = 0;
sleep_time.tv_nsec = usecs * 1000; sleep_time.tv_nsec = usecs * 1000;
nanosleep(&sleep_time, NULL); nanosleep(&sleep_time, NULL);
} }
/* not really an SSDP "announce" as it is the response /* not really an SSDP "announce" as it is the response
* to a SSDP "M-SEARCH" */ * to a SSDP "M-SEARCH" */
static void static void
SendSSDPResponse(int s, struct sockaddr_in sockname, int st_no, SendSSDPResponse(int s, struct sockaddr_in sockname, int st_no,
skipping to change at line 281 skipping to change at line 292
memset(&sockname, 0, sizeof(struct sockaddr_in)); memset(&sockname, 0, sizeof(struct sockaddr_in));
sockname.sin_family = AF_INET; sockname.sin_family = AF_INET;
sockname.sin_port = htons(SSDP_PORT); sockname.sin_port = htons(SSDP_PORT);
sockname.sin_addr.s_addr = inet_addr(SSDP_MCAST_ADDR); sockname.sin_addr.s_addr = inet_addr(SSDP_MCAST_ADDR);
lifetime = (interval << 1) + 10; lifetime = (interval << 1) + 10;
for (dup = 0; dup < 2; dup++) for (dup = 0; dup < 2; dup++)
{ {
if (dup) if (dup)
_usleep(200000); _usleep(150000, 250000);
i = 0; i = 0;
while (known_service_types[i]) while (known_service_types[i])
{ {
l = snprintf(bufr, sizeof(bufr), l = snprintf(bufr, sizeof(bufr),
"NOTIFY * HTTP/1.1\r\n" "NOTIFY * HTTP/1.1\r\n"
"HOST:%s:%d\r\n" "HOST:%s:%d\r\n"
"CACHE-CONTROL:max-age=%u\r\n" "CACHE-CONTROL:max-age=%u\r\n"
"LOCATION:http://%s:%d" ROOTDESC_PATH"\r\ n" "LOCATION:http://%s:%d" ROOTDESC_PATH"\r\ n"
"SERVER: " MINIDLNA_SERVER_STRING "\r\n" "SERVER: " MINIDLNA_SERVER_STRING "\r\n"
"NT:%s%s\r\n" "NT:%s%s\r\n"
skipping to change at line 484 skipping to change at line 495
else else
{ {
client->type = &client_types[type]; client->type = &client_types[type];
client->age = time(NULL); client->age = time(NULL);
} }
} }
/* ProcessSSDPRequest() /* ProcessSSDPRequest()
* process SSDP M-SEARCH requests and responds to them */ * process SSDP M-SEARCH requests and responds to them */
void void
ProcessSSDPRequest(int s, unsigned short port) ProcessSSDPRequest(struct event *ev)
{ {
int s = ev->fd;
int n; int n;
char bufr[1500]; char bufr[1500];
struct sockaddr_in sendername; struct sockaddr_in sendername;
int i; int i;
char *st = NULL, *mx = NULL, *man = NULL, *mx_end = NULL; char *st = NULL, *mx = NULL, *man = NULL, *mx_end = NULL;
int man_len = 0; int man_len = 0;
socklen_t len_r = sizeof(struct sockaddr_in); socklen_t len_r = sizeof(struct sockaddr_in);
#ifdef __linux__ #ifdef __linux__
char cmbuf[CMSG_SPACE(sizeof(struct in_pktinfo))]; char cmbuf[CMSG_SPACE(sizeof(struct in_pktinfo))];
struct iovec iovec = { struct iovec iovec = {
skipping to change at line 671 skipping to change at line 683
struct in_addr addr; struct in_addr addr;
struct in_pktinfo *pi; struct in_pktinfo *pi;
/* ignore the control headers that don't match wh at we want */ /* ignore the control headers that don't match wh at we want */
if (cmsg->cmsg_level != IPPROTO_IP || if (cmsg->cmsg_level != IPPROTO_IP ||
cmsg->cmsg_type != IP_PKTINFO) cmsg->cmsg_type != IP_PKTINFO)
continue; continue;
pi = (struct in_pktinfo *)CMSG_DATA(cmsg); pi = (struct in_pktinfo *)CMSG_DATA(cmsg);
addr = pi->ipi_spec_dst; addr = pi->ipi_spec_dst;
inet_ntop(AF_INET, &addr, host, sizeof(host)); inet_ntop(AF_INET, &addr, host, sizeof(host));
for (i = 0; i < n_lan_addr; i++)
{
if (pi->ipi_ifindex == lan_addr[i].ifinde
x)
break;
}
} }
#else #else
const char *host; const char *host;
int iface = 0; int iface = 0;
/* find in which sub network the client is */ /* find in which sub network the client is */
for (i = 0; i < n_lan_addr; i++) for (i = 0; i < n_lan_addr; i++)
{ {
if((sendername.sin_addr.s_addr & lan_addr[i].mask .s_addr) == if((sendername.sin_addr.s_addr & lan_addr[i].mask .s_addr) ==
(lan_addr[i].addr.s_addr & lan_addr[i].mask.s_ addr)) (lan_addr[i].addr.s_addr & lan_addr[i].mask.s_ addr))
{ {
iface = i; iface = i;
break; break;
} }
} }
host = lan_addr[iface].str;
#endif
if (n_lan_addr == i) if (n_lan_addr == i)
{ {
DPRINTF(E_DEBUG, L_SSDP, "Ignoring SSDP M-SEARCH on other interface [%s]\n", DPRINTF(E_DEBUG, L_SSDP, "Ignoring SSDP M-SEARCH on other interface [%s]\n",
inet_ntoa(sendername.sin_addr)); inet_ntoa(sendername.sin_addr));
return; return;
} }
host = lan_addr[iface].str;
#endif
DPRINTF(E_DEBUG, L_SSDP, "SSDP M-SEARCH from %s:%d ST: %. *s, MX: %.*s, MAN: %.*s\n", DPRINTF(E_DEBUG, L_SSDP, "SSDP M-SEARCH from %s:%d ST: %. *s, MX: %.*s, MAN: %.*s\n",
inet_ntoa(sendername.sin_addr), inet_ntoa(sendername.sin_addr),
ntohs(sendername.sin_port), ntohs(sendername.sin_port),
st_len, st, mx_len, mx, man_len, man); st_len, st, mx_len, mx, man_len, man);
/* Responds to request with a device as ST header */ /* Responds to request with a device as ST header */
for (i = 0; known_service_types[i]; i++) for (i = 0; known_service_types[i]; i++)
{ {
l = strlen(known_service_types[i]); l = strlen(known_service_types[i]);
if ((l > st_len) || (memcmp(st, known_service_typ es[i], l) != 0)) if ((l > st_len) || (memcmp(st, known_service_typ es[i], l) != 0))
continue; continue;
skipping to change at line 725 skipping to change at line 742
continue; continue;
} }
DPRINTF(E_MAXDEBUG, L_SSDP, DPRINTF(E_MAXDEBUG, L_SSDP,
"Ignoring SSDP M-SEARCH w ith bad extra data '%c' [%s]\n", "Ignoring SSDP M-SEARCH w ith bad extra data '%c' [%s]\n",
st[l], inet_ntoa(senderna me.sin_addr)); st[l], inet_ntoa(senderna me.sin_addr));
break; break;
} }
if (l != st_len) if (l != st_len)
break; break;
} }
_usleep(random()>>20); _usleep(13000, 20000);
SendSSDPResponse(s, sendername, i, SendSSDPResponse(s, sendername, i, host,
host, port, len_r); (unsigned short)runtime_vars.port, len_r);
return; return;
} }
/* Responds to request with ST: ssdp:all */ /* Responds to request with ST: ssdp:all */
/* strlen("ssdp:all") == 8 */ /* strlen("ssdp:all") == 8 */
if ((st_len == 8) && (memcmp(st, "ssdp:all", 8) == 0)) if ((st_len == 8) && (memcmp(st, "ssdp:all", 8) == 0))
{ {
_usleep(13000, 30000);
for (i=0; known_service_types[i]; i++) for (i=0; known_service_types[i]; i++)
{ {
l = strlen(known_service_types[i]); l = strlen(known_service_types[i]);
SendSSDPResponse(s, sendername, i, SendSSDPResponse(s, sendername, i, host,
host, port, len_r); (unsigned short)runtime_vars.port,
len_r);
} }
} }
} }
else else
{ {
DPRINTF(E_INFO, L_SSDP, "Invalid SSDP M-SEARCH from %s:%d \n", DPRINTF(E_INFO, L_SSDP, "Invalid SSDP M-SEARCH from %s:%d \n",
inet_ntoa(sendername.sin_addr), ntohs(sendername. sin_port)); inet_ntoa(sendername.sin_addr), ntohs(sendername. sin_port));
} }
} }
else if (memcmp(bufr, "YOUKU-NOTIFY", 12) == 0) else if (memcmp(bufr, "YOUKU-NOTIFY", 12) == 0)
 End of changes. 16 change blocks. 
14 lines changed or deleted 34 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)