Backport of svn revision 504:

SF Patch Tracker [ 2969188 ] 1.8.0: patch for FreeBSD compilation
	Submitted By: Nick Leverton (leveret)
	Fix the order of header inclusion for FreeBSD.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@509 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez 2010-03-21 15:42:40 +00:00
parent 9226dd833b
commit 5eb55e0fb2
9 changed files with 386 additions and 346 deletions

View File

@ -2,6 +2,12 @@
Version 1.6.7
*******************************************************************************
2010-03-20 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Backport of svn revision 504:
SF Patch Tracker [ 2969188 ] 1.8.0: patch for FreeBSD compilation
Submitted By: Nick Leverton (leveret)
Fix the order of header inclusion for FreeBSD.
2010-03-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
Submitted By: zephyrus ( zephyrus00jp )

View File

@ -29,80 +29,134 @@
*
******************************************************************************/
#ifndef THREADPOOL_H
#define THREADPOOL_H
#ifdef UPNP_USE_MSVCPP
#define UPNP_INLINE
#else
#define UPNP_INLINE inline
/*!
* \file
*/
#include "FreeList.h"
#include "ithread.h"
#include "LinkedList.h"
#include "UpnpInet.h"
#include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */
#include <errno.h>
#ifdef WIN32
#include <time.h>
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#else /* WIN32 */
#include <sys/param.h>
#include <sys/time.h> /* for gettimeofday() */
#if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__)
#include <sys/resource.h> /* for setpriority() */
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Size of job free list */
/*! Size of job free list */
#define JOBFREELISTSIZE 100
#define INFINITE_THREADS -1
#define EMAXTHREADS (-8 & 1<<29)
/* Invalid Policy */
/*! Invalid Policy */
#define INVALID_POLICY (-9 & 1<<29)
/* Invalid JOB Id */
/*! Invalid JOB Id */
#define INVALID_JOB_ID (-2 & 1<<29)
typedef enum duration {SHORT_TERM,PERSISTENT} Duration;
typedef enum priority {LOW_PRIORITY,
MED_PRIORITY,
HIGH_PRIORITY} ThreadPriority;
typedef enum duration {
SHORT_TERM,
PERSISTENT
} Duration;
#define DEFAULT_PRIORITY MED_PRIORITY /* default priority used by TPJobInit */
#define DEFAULT_MIN_THREADS 1 /* default minimum used by TPAttrInit */
#define DEFAULT_MAX_THREADS 10 /* default max used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10 /* default jobs per thread used by TPAttrInit */
#define DEFAULT_STARVATION_TIME 500 /* default starvation time used by TPAttrInit */
#define DEFAULT_IDLE_TIME 10 * 1000 /* default idle time used by TPAttrInit */
#define DEFAULT_FREE_ROUTINE NULL /* default free routine used TPJobInit */
#define DEFAULT_MAX_JOBS_TOTAL 100 /* default max jobs used TPAttrInit */
/* Statistics */
/* always include stats because code change is minimal */
typedef enum priority {
LOW_PRIORITY,
MED_PRIORITY,
HIGH_PRIORITY
} ThreadPriority;
/*! default priority used by TPJobInit */
#define DEFAULT_PRIORITY MED_PRIORITY
/*! default minimum used by TPAttrInit */
#define DEFAULT_MIN_THREADS 1
/*! default max used by TPAttrInit */
#define DEFAULT_MAX_THREADS 10
/*! default jobs per thread used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10
/*! default starvation time used by TPAttrInit */
#define DEFAULT_STARVATION_TIME 500
/*! default idle time used by TPAttrInit */
#define DEFAULT_IDLE_TIME 10 * 1000
/*! default free routine used TPJobInit */
#define DEFAULT_FREE_ROUTINE NULL
/*! default max jobs used TPAttrInit */
#define DEFAULT_MAX_JOBS_TOTAL 100
/*!
* \brief Statistics.
*
* Always include stats because code change is minimal.
*/
#define STATS 1
#ifdef _DEBUG
#define DEBUG 1
#endif
#include "LinkedList.h"
#ifdef WIN32
#include <time.h>
#include <winsock2.h>
struct timezone
{
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
};
int gettimeofday(struct timeval *tv, struct timezone *tz);
#else /* WIN32 */
#include <sys/time.h> /* for gettimeofday() */
#endif
#include "FreeList.h"
#include "ithread.h"
#include <errno.h>
#define EXPORT
typedef int PolicyType;
#define DEFAULT_POLICY SCHED_OTHER
#define DEFAULT_SCHED_PARAM 0 /* default priority */
/*! Default priority */
#define DEFAULT_SCHED_PARAM 0
/****************************************************************************
* Name: free_routine
@ -112,6 +166,7 @@ typedef int PolicyType;
*****************************************************************************/
typedef void (*free_routine)(void *arg);
/****************************************************************************
* Name: ThreadPoolAttr
*
@ -145,6 +200,7 @@ typedef struct THREADPOOLATTR
PolicyType schedPolicy;
} ThreadPoolAttr;
/****************************************************************************
* Name: ThreadPool
*
@ -161,13 +217,13 @@ typedef struct THREADPOOLJOB
int jobId;
} ThreadPoolJob;
/****************************************************************************
* Name: ThreadPoolStats
*
* Description:
* Structure to hold statistics
*****************************************************************************/
typedef struct TPOOLSTATS
{
double totalTimeHQ;
@ -192,26 +248,21 @@ typedef struct TPOOLSTATS
} ThreadPoolStats;
/****************************************************************************
* Name: ThreadPool
/*!
* \brief A thread pool similar to the thread pool in the UPnP SDK.
*
* Description:
* A thread pool similar to the thread pool in the UPnP SDK.
* Allows jobs to be scheduled for running by threads in a
* thread pool. The thread pool is initialized with a
* minimum and maximum thread number as well as a
* max idle time
* and a jobs per thread ratio. If a worker thread waits the whole
* max idle time without receiving a job and the thread pool
* currently has more threads running than the minimum
* then the worker thread will exit. If when
* scheduling a job the current job to thread ratio
* becomes greater than the set ratio and the thread pool currently has
* less than the maximum threads then a new thread will
* be created.
*
*****************************************************************************/
* Allows jobs to be scheduled for running by threads in a
* thread pool. The thread pool is initialized with a
* minimum and maximum thread number as well as a max idle time
* and a jobs per thread ratio. If a worker thread waits the whole
* max idle time without receiving a job and the thread pool
* currently has more threads running than the minimum
* then the worker thread will exit. If when
* scheduling a job the current job to thread ratio
* becomes greater than the set ratio and the thread pool currently has
* less than the maximum threads then a new thread will
* be created.
*/
typedef struct THREADPOOL
{
ithread_mutex_t mutex; /* mutex to protect job qs */
@ -235,7 +286,6 @@ typedef struct THREADPOOL
} ThreadPool;
/****************************************************************************
* Function: ThreadPoolInit
*
@ -274,6 +324,7 @@ typedef struct THREADPOOL
*****************************************************************************/
int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolAddPersistent
*
@ -296,6 +347,7 @@ int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr);
*****************************************************************************/
int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId);
/****************************************************************************
* Function: ThreadPoolGetAttr
*
@ -310,6 +362,8 @@ int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId);
* Always returns 0.
*****************************************************************************/
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out);
/****************************************************************************
* Function: ThreadPoolSetAttr
*
@ -325,6 +379,7 @@ int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out);
*****************************************************************************/
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolAdd
*
@ -344,6 +399,7 @@ int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr);
*****************************************************************************/
int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId);
/****************************************************************************
* Function: ThreadPoolRemove
*
@ -396,6 +452,7 @@ int ThreadPoolShutdown(ThreadPool *tp);
*****************************************************************************/
int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
/****************************************************************************
* Function: TPJobSetPriority
*
@ -409,6 +466,7 @@ int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
*****************************************************************************/
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
/****************************************************************************
* Function: TPJobSetFreeFunction
*
@ -422,6 +480,7 @@ int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
*****************************************************************************/
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
/****************************************************************************
* Function: TPAttrInit
*
@ -435,6 +494,7 @@ int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
*****************************************************************************/
int TPAttrInit(ThreadPoolAttr *attr);
/****************************************************************************
* Function: TPAttrSetMaxThreads
*
@ -448,6 +508,7 @@ int TPAttrInit(ThreadPoolAttr *attr);
*****************************************************************************/
int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
/****************************************************************************
* Function: TPAttrSetMinThreads
*
@ -461,6 +522,7 @@ int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
*****************************************************************************/
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
/****************************************************************************
* Function: TPAttrSetIdleTime
*
@ -473,6 +535,7 @@ int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
*****************************************************************************/
int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
/****************************************************************************
* Function: TPAttrSetJobsPerThread
*
@ -486,6 +549,7 @@ int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
*****************************************************************************/
int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
/****************************************************************************
* Function: TPAttrSetStarvationTime
*
@ -499,6 +563,7 @@ int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
*****************************************************************************/
int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
/****************************************************************************
* Function: TPAttrSetSchedPolicy
*
@ -526,6 +591,7 @@ int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
*****************************************************************************/
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
/****************************************************************************
* Function: ThreadPoolGetStats
*
@ -540,18 +606,20 @@ int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
* Always returns 0.
*****************************************************************************/
#ifdef STATS
EXPORT int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats);
EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats);
EXPORT void ThreadPoolPrintStats(ThreadPoolStats *stats);
EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats);
#else
static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {}
static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {}
#endif
#ifdef __cplusplus
}
#endif
#endif /* ThreadPool */
#endif /* THREADPOOL_H */

View File

@ -29,22 +29,40 @@
*
******************************************************************************/
#ifndef ITHREADH
#define ITHREADH
/*!
* \file
*/
#if ! defined(WIN32)
#include <sys/param.h>
#endif
#include "UpnpGlobal.h" /* For EXPORT_SPEC */
#ifdef __cplusplus
extern "C" {
#endif
#include <pthread.h>
#ifndef WIN32
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
#ifdef __FreeBSD__
#if defined(BSD)
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif
#ifdef PTHREAD_MUTEX_RECURSIVE
/* This system has SuS2-compliant mutex attributes.
* E.g. on Cygwin, where we don't have the old nonportable (NP) symbols
@ -715,10 +733,10 @@ typedef pthread_rwlock_t ithread_rwlock_t;
* 0 on success, Nonzero on failure.
* See man page for sleep (man 3 sleep)
*****************************************************************************/
#ifndef WIN32
#define isleep sleep
#ifdef WIN32
#define isleep(x) Sleep((x)*1000)
#else
#define isleep(x) Sleep((x)*1000)
#define isleep sleep
#endif
/****************************************************************************
@ -734,25 +752,10 @@ typedef pthread_rwlock_t ithread_rwlock_t;
* 0 on success, Nonzero on failure.
* See man page for sleep (man 3 sleep)
*****************************************************************************/
#ifndef WIN32
#define imillisleep(x) usleep(1000*x)
#else
#define imillisleep Sleep
#endif
#ifdef WIN32
#ifndef UPNP_STATIC_LIB
#ifdef LIBUPNP_EXPORTS
/* set up declspec for dll export to make functions visible to library users */
#define EXPORT_SPEC __declspec(dllexport)
#else
#define EXPORT_SPEC __declspec(dllimport)
#endif
#else
#define EXPORT_SPEC
#endif
#define imillisleep Sleep
#else
#define EXPORT_SPEC
#define imillisleep(x) usleep(1000*x)
#endif

View File

@ -29,13 +29,28 @@
*
******************************************************************************/
/*!
* \file
*/
#if ! defined(WIN32)
#include <sys/param.h>
#endif
#include "ThreadPool.h"
#include "FreeList.h"
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* for memset()*/
/****************************************************************************
* Function: DiffMillis
*
@ -218,7 +233,7 @@ static void FreeThreadPoolJob(ThreadPool *tp, ThreadPoolJob *tpj)
* Sets the scheduling policy of the current process.
* Internal only.
* Parameters:
* PolocyType in
* PolicyType in
* Returns:
* 0 on success, nonzero on failure
* Returns result of GetLastError() on failure.
@ -229,7 +244,7 @@ static int SetPolicyType(PolicyType in)
#ifdef __CYGWIN__
/* TODO not currently working... */
return 0;
#elif defined(__OSX__) || defined(__APPLE__)
#elif defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__)
setpriority(PRIO_PROCESS, 0, 0);
return 0;
#elif defined(WIN32)
@ -278,6 +293,7 @@ static int SetPriority(ThreadPriority priority)
int actPriority = 0;
int midPriority = 0;
struct sched_param newPriority;
int sched_result;
pthread_getschedparam(ithread_self(), &currentPolicy, &newPriority);
minPriority = sched_get_priority_min(currentPolicy);
@ -299,7 +315,8 @@ static int SetPriority(ThreadPriority priority)
newPriority.sched_priority = actPriority;
return pthread_setschedparam(ithread_self(), currentPolicy, &newPriority);
sched_result = pthread_setschedparam(ithread_self(), currentPolicy, &newPriority);
return (0 == sched_result || EPERM == errno) ? 0 : -1;
#else
return 0;
#endif
@ -398,7 +415,7 @@ static void SetSeed()
gettimeofday(&t, NULL);
#if defined(WIN32)
srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id().p );
#elif defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)
#elif defined(BSD) || defined(__OSX__) || defined(__APPLE__) || defined(__FreeBSD_kernel__)
srand( ( unsigned int )t.tv_usec + (unsigned int)ithread_get_current_thread_id() );
#elif defined(__linux__) || defined(__sun) || defined(__CYGWIN__) || defined(__GLIBC__)
srand( ( unsigned int )t.tv_usec + ithread_get_current_thread_id() );
@ -1515,6 +1532,7 @@ int TPAttrSetMaxJobsTotal( ThreadPoolAttr *attr, int maxJobsTotal )
return 0;
}
#ifdef STATS
void ThreadPoolPrintStats(ThreadPoolStats *stats)
{
@ -1523,11 +1541,8 @@ void ThreadPoolPrintStats(ThreadPoolStats *stats)
return;
}
#ifdef __FreeBSD__
printf("ThreadPoolStats at Time: %d\n", StatsTime(NULL));
#else /* __FreeBSD__ */
printf("ThreadPoolStats at Time: %ld\n", StatsTime(NULL));
#endif /* __FreeBSD__ */
/* some OSses time_t length may depending on platform, promote it to long for safety */
printf("ThreadPoolStats at Time: %ld\n", (long)StatsTime(NULL));
printf("High Jobs pending: %d\n", stats->currentJobsHQ);
printf("Med Jobs Pending: %d\n", stats->currentJobsMQ);
printf("Low Jobs Pending: %d\n", stats->currentJobsLQ);
@ -1544,6 +1559,7 @@ void ThreadPoolPrintStats(ThreadPoolStats *stats)
}
#endif /* STATS */
/****************************************************************************
* Function: ThreadPoolGetStats
*
@ -1606,6 +1622,7 @@ int ThreadPoolGetStats( ThreadPool *tp, ThreadPoolStats *stats )
#endif /* STATS */
#ifdef WIN32
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64

View File

@ -15,6 +15,13 @@
#include <winsock2.h>
#include <Ws2tcpip.h>
#else
#include <sys/param.h>
#if (defined(BSD) && BSD >= 199306) || defined (__FreeBSD_kernel__)
#include <ifaddrs.h>
/* Do not move or remove the include below for "sys/socket"!
* Will break FreeBSD builds. */
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#endif

View File

@ -50,6 +50,7 @@
#include "uri.h"
#include "statcodes.h"
#include "sock.h"
#include "UpnpInet.h"
#include "webserver.h"
@ -66,12 +67,10 @@
#ifdef WIN32
#include <winsock2.h>
#include <malloc.h>
#else
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
@ -185,13 +184,13 @@ http_Connect( IN uri_type * destination_url,
http_FixUrl( destination_url, url );
connfd = socket( AF_INET, SOCK_STREAM, 0 );
connfd = socket( url->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( connfd == -1 ) {
return UPNP_E_OUTOF_SOCKET;
}
if( connect( connfd, ( struct sockaddr * )&url->hostport.IPv4address,
sizeof( struct sockaddr_in ) ) == -1 ) {
if( connect( connfd, ( struct sockaddr * )&url->hostport.IPaddress,
sizeof( url->hostport.IPaddress ) ) == -1 ) {
#ifdef WIN32
UpnpPrintf(UPNP_CRITICAL, HTTP, __FILE__, __LINE__,
"connect error: %d\n", WSAGetLastError());
@ -550,7 +549,7 @@ http_RequestAndResponse( IN uri_type * destination,
int http_error_code;
SOCKINFO info;
tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
tcp_connection = socket( destination->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
parser_response_init( response, req_method );
return UPNP_E_SOCKET_ERROR;
@ -564,7 +563,7 @@ http_RequestAndResponse( IN uri_type * destination,
// connect
ret_code = connect( info.socket,
( struct sockaddr * )&destination->hostport.
IPv4address, sizeof( struct sockaddr_in ) );
IPaddress, sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &info, SD_BOTH );
@ -1035,7 +1034,7 @@ http_OpenHttpPost( IN const char *url_str,
handle->contentLength = contentLength;
tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
tcp_connection = socket( url.hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler;
@ -1049,8 +1048,8 @@ http_OpenHttpPost( IN const char *url_str,
}
ret_code = connect( handle->sock_info.socket,
( struct sockaddr * )&url.hostport.IPv4address,
sizeof( struct sockaddr_in ) );
( struct sockaddr * )&url.hostport.IPaddress,
sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
@ -1617,7 +1616,7 @@ http_OpenHttpGetProxy( IN const char *url_str,
handle->cancel = 0;
parser_response_init( &handle->response, HTTPMETHOD_GET );
tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
tcp_connection = socket( peer->hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
ret_code = UPNP_E_SOCKET_ERROR;
goto errorHandler;
@ -1631,8 +1630,8 @@ http_OpenHttpGetProxy( IN const char *url_str,
}
ret_code = connect( handle->sock_info.socket,
( struct sockaddr * )&peer->hostport.IPv4address,
sizeof( struct sockaddr_in ) );
( struct sockaddr * )&peer->hostport.IPaddress,
sizeof( struct sockaddr_storage ) );
if( ret_code == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
@ -2266,7 +2265,7 @@ http_OpenHttpGetEx( IN const char *url_str,
handle->entity_offset = 0;
parser_response_init( &handle->response, HTTPMETHOD_GET );
tcp_connection = socket( AF_INET, SOCK_STREAM, 0 );
tcp_connection = socket( url.hostport.IPaddress.ss_family, SOCK_STREAM, 0 );
if( tcp_connection == -1 ) {
errCode = UPNP_E_SOCKET_ERROR;
free( handle );
@ -2282,8 +2281,8 @@ http_OpenHttpGetEx( IN const char *url_str,
}
errCode = connect( handle->sock_info.socket,
( struct sockaddr * )&url.hostport.IPv4address,
sizeof( struct sockaddr_in ) );
( struct sockaddr * )&url.hostport.IPaddress,
sizeof( struct sockaddr_storage ) );
if( errCode == -1 ) {
sock_destroy( &handle->sock_info, SD_BOTH );
errCode = UPNP_E_SOCKET_CONNECT;

View File

@ -43,6 +43,7 @@
#include <lwres/netdb.h>
#endif
#endif
#include <assert.h>
#include "config.h"
@ -51,7 +52,7 @@
#include "uri.h"
#include "upnpdebug.h"
#include "upnpapi.h"
/*!
@ -187,28 +188,6 @@ static int parse_uric(
return i;
}
/************************************************************************
* Function : copy_sockaddr_in
*
* Parameters :
* const struct sockaddr_in *in ; Source socket address object
* struct sockaddr_in *out ; Destination socket address object
*
* Description : Copies one socket address into another
*
* Return : void ;
*
* Note :
************************************************************************/
void
copy_sockaddr_in( const struct sockaddr_in *in,
struct sockaddr_in *out )
{
memset( out->sin_zero, 0, 8 );
out->sin_family = in->sin_family;
out->sin_port = in->sin_port;
out->sin_addr.s_addr = in->sin_addr.s_addr;
}
/*!
* \brief Tokens are generally pointers into other strings. This copies the
@ -263,8 +242,9 @@ int copy_URL_list(URL_list *in, URL_list *out)
in->URLs, &out->parsedURLs[i].hostport.text,
out->URLs );
copy_sockaddr_in( &in->parsedURLs[i].hostport.IPv4address,
&out->parsedURLs[i].hostport.IPv4address );
memcpy( &out->parsedURLs[i].hostport.IPaddress,
&in->parsedURLs[i].hostport.IPaddress,
sizeof(struct sockaddr_storage) );
}
out->size = in->size;
@ -343,186 +323,156 @@ int token_cmp(token *in1, token *in2)
}
int parse_port(int max, const char *port, unsigned short *out)
{
const char *finger = port;
const char *max_ptr = finger + max;
unsigned short temp = 0;
while((finger < max_ptr) && (isdigit(*finger))) {
temp = temp * 10;
temp += *finger - '0';
finger++;
}
*out = htons(temp);
return finger - port;
}
int parse_hostport(
const char *in,
int max,
hostport_type *out)
{
#define BUFFER_SIZE 8192
int i = 0;
int begin_port;
int hostport_size = 0;
int host_size = 0;
#if !defined(WIN32) && !(defined(__OSX__) || defined(__APPLE__))
char temp_hostbyname_buff[BUFFER_SIZE];
struct hostent h_buf;
#endif
struct hostent *h = NULL;
int errcode = 0;
char *temp_host_name = NULL;
int last_dot = -1;
char workbuf[256];
char* c;
struct sockaddr_in* sai4 = (struct sockaddr_in*)&out->IPaddress;
struct sockaddr_in6* sai6 = (struct sockaddr_in6*)&out->IPaddress;
char *srvname = NULL;
char *srvport = NULL;
char *last_dot = NULL;
unsigned short int port;
int af = AF_UNSPEC;
int hostport_size;
int has_port = 0;
int ret;
memset( out, 0, sizeof(hostport_type) );
out->IPv4address.sin_port = htons( 80 ); //default port is 80
memset( &out->IPv4address.sin_zero, 0, 8 );
// Work on a copy of the input string.
strncpy( workbuf, in, sizeof(workbuf) );
while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' )
&& ( ( isalnum( in[i] ) ) || ( in[i] == '.' )
|| ( in[i] == '-' ) ) ) {
i++;
if( in[i] == '.' ) {
last_dot = i;
c = workbuf;
if( *c == '[' ) {
// IPv6 addresses are enclosed in square brackets.
srvname = ++c;
while( *c != '\0' && *c != ']' ) {
c++;
}
if( *c == '\0' ) {
// did not find closing bracket.
return UPNP_E_INVALID_URL;
}
// NULL terminate the srvname and then increment c.
*c++ = '\0'; // overwrite the ']'
if( *c == ':' ) {
has_port = 1;
c++;
}
af = AF_INET6;
}
host_size = i;
if( ( i < max ) && ( in[i] == ':' ) ) {
begin_port = i + 1;
//convert port
if( !( hostport_size = parse_port( max - begin_port,
&in[begin_port],
&out->IPv4address.sin_port ) ) )
{
return UPNP_E_INVALID_URL;
else {
// IPv4 address -OR- host name.
srvname = c;
while( (*c != ':') && (*c != '/') && ( (isalnum(*c)) || (*c == '.') || (*c == '-') ) ) {
if( *c == '.' )
last_dot = c;
c++;
}
hostport_size += begin_port;
} else
hostport_size = host_size;
has_port = (*c == ':') ? 1 : 0;
// NULL terminate the srvname
*c = '\0';
if( has_port == 1 )
c++;
//convert to temporary null terminated string
temp_host_name = ( char * )malloc( host_size + 1 );
if( temp_host_name == NULL )
return UPNP_E_OUTOF_MEMORY;
memcpy( temp_host_name, in, host_size );
temp_host_name[host_size] = '\0';
//check to see if host name is an ipv4 address
if( ( last_dot != -1 ) && ( last_dot + 1 < host_size )
&& ( isdigit( temp_host_name[last_dot + 1] ) ) ) {
//must be ipv4 address
errcode = inet_pton( AF_INET,
temp_host_name, &out->IPv4address.sin_addr );
if( errcode == 1 ) {
out->IPv4address.sin_family = AF_INET;
} else {
out->IPv4address.sin_addr.s_addr = 0;
out->IPv4address.sin_family = AF_INET;
free( temp_host_name );
temp_host_name = NULL;
return UPNP_E_INVALID_URL;
if( last_dot != NULL && isdigit(*(last_dot+1)) ) {
// Must be an IPv4 address.
af = AF_INET;
}
} else {
int errCode = 0;
//call gethostbyname_r (reentrant form of gethostbyname)
// TODO: Use autoconf to discover this rather than the
// platform-specific stuff below
#if defined(WIN32) || defined(__CYGWIN__)
h = gethostbyname(temp_host_name);
#elif defined(SPARC_SOLARIS)
errCode = gethostbyname_r(
temp_host_name,
&h,
temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
#elif defined(__FreeBSD__) && __FreeBSD_version < 601103
h = lwres_gethostbyname_r(
temp_host_name,
&h_buf,
temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
if ( h == NULL ) {
errCode = 1;
}
#elif defined(__OSX__) || defined(__APPLE__)
h = gethostbyname(temp_host_name);
if ( h == NULL ) {
errCode = 1;
}
#elif defined(__linux__)
errCode = gethostbyname_r(
temp_host_name,
&h_buf,
temp_hostbyname_buff,
BUFFER_SIZE, &h, &errcode );
#else
{
else {
// Must be a host name.
struct addrinfo hints, *res, *res0;
h = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM;
errCode = getaddrinfo(temp_host_name, "http", &hints, &res0);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (!errCode) {
for (res = res0; res; res = res->ai_next) {
if (res->ai_family == PF_INET &&
res->ai_addr->sa_family == AF_INET)
{
h = &h_buf;
h->h_addrtype = res->ai_addr->sa_family;
h->h_length = 4;
h->h_addr = (void *) temp_hostbyname_buff;
*(struct in_addr *)h->h_addr =
((struct sockaddr_in *)res->ai_addr)->sin_addr;
ret = getaddrinfo(srvname, NULL, &hints, &res0);
if( ret == 0 ) {
for (res = res0; res; res = res->ai_next) {
if( res->ai_family == AF_INET ||
res->ai_family == AF_INET6 ) {
// Found a valid IPv4 or IPv6 address.
memcpy( &out->IPaddress, res->ai_addr,
res->ai_addrlen );
break;
}
}
}
freeaddrinfo(res0);
}
}
#endif
if( errCode == 0 ) {
if( h ) {
if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {
out->IPv4address.sin_addr =
( *( struct in_addr * )h->h_addr );
out->IPv4address.sin_family = AF_INET;
freeaddrinfo(res0);
if( res == NULL ) {
// Didn't find an AF_INET or AF_INET6 address.
return UPNP_E_INVALID_URL;
}
}
} else {
out->IPv4address.sin_addr.s_addr = 0;
out->IPv4address.sin_family = AF_INET;
free( temp_host_name );
temp_host_name = NULL;
return UPNP_E_INVALID_URL;
else {
// getaddrinfo failed.
return UPNP_E_INVALID_URL;
}
}
}
if( temp_host_name ) {
free( temp_host_name );
temp_host_name = NULL;
// Check if a port is specified.
if( has_port == 1 ) {
// Port is specified.
srvport = c;
while( *c != '\0' && isdigit(*c) ) {
c++;
}
port = (unsigned short int)atoi(srvport);
if( port == 0 ) {
// Bad port number.
return UPNP_E_INVALID_URL;
}
}
else {
// Port was not specified, use default port.
port = 80;
}
// The length of the host and port string can be calculated by
// subtracting pointers.
hostport_size = (int)(c - workbuf);
// Fill in the 'out' information.
if( af == AF_INET ) {
sai4->sin_family = AF_INET;
sai4->sin_port = htons(port);
ret = inet_pton(AF_INET, srvname, &sai4->sin_addr);
}
else if( af == AF_INET6 ) {
sai6->sin6_family = AF_INET6;
sai6->sin6_port = htons(port);
/*
sai6->sin6_scope_id = gIF_INDEX;
ret = inet_pton(AF_INET6, srvname, &sai6->sin6_addr);
*/
/* libUPnP 1.6.x does not currently support IPV6. */
assert(0);
ret = -1;
} else {
// IP address was set by the hostname (getaddrinfo).
// Override port:
if( out->IPaddress.ss_family == AF_INET )
sai4->sin_port = htons(port);
else
sai6->sin6_port = htons(port);
ret = 1;
}
/* Check if address was converted successfully. */
if (ret <= 0) {
return UPNP_E_INVALID_URL;
}
out->text.size = hostport_size;
out->text.buff = in;
return hostport_size;
return hostport_size;
}
/*!

View File

@ -38,6 +38,10 @@
* \file
*/
#if !defined(WIN32)
#include <sys/param.h>
#endif
#include "UpnpGlobal.h" /* for */
#include "UpnpInet.h"
@ -48,6 +52,9 @@
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#if defined(BSD)
#include <sys/socket.h>
#endif
#include <sys/types.h>
#include <time.h>
@ -131,7 +138,7 @@ typedef struct HOSTPORT {
/*! Full host port. */
token text;
/* Network Byte Order */
struct sockaddr_in IPv4address;
struct sockaddr_storage IPaddress;
} hostport_type;
@ -280,22 +287,6 @@ int token_cmp(
token *in2);
/*!
* \brief Parses a port (i.e. '4000') and converts it into a network ordered
* unsigned short int.
*
* \return
*/
int parse_port(
/*! [in] Sets a maximum limit. */
int max,
/*! [in] Port to be parsed. */
const char *port,
/*! [out] Output parameter where the port is parsed and converted into
* network format. */
unsigned short int *out);
/*!
* \brief Parses a string representing a host and port (e.g. "127.127.0.1:80"
* or "localhost") and fills out a hostport_type struct with internet address

View File

@ -1,35 +1,41 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
#if !defined(WIN32)
#include <sys/param.h>
#endif
#include "config.h"
#if EXCLUDE_SSDP == 0
#include "membuffer.h"
@ -42,13 +48,6 @@
#include "httpparser.h"
#include "httpreadwrite.h"
#ifdef WIN32
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "unixutil.h"
#endif
#define MAX_TIME_TOREAD 45
CLIENTONLY( SOCKET gSsdpReqSocket = 0; )
@ -850,7 +849,7 @@ readFromSSDPSocket( SOCKET socket )
* Function : get_ssdp_sockets
*
* Parameters:
* OUT MiniServerSockArray *out: Arrays of SSDP sockets
* OUT MiniServerSockArray *out: Array of SSDP sockets
*
* Description:
* This function creates the ssdp sockets. It set their option to listen
@ -915,7 +914,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
return UPNP_E_SOCKET_ERROR;
}
#if defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)
#if defined(BSD) || defined(__OSX__) || defined(__APPLE__)
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
(char *)&onOff, sizeof (onOff) );
if ( ret == -1 ) {
@ -929,7 +928,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
return UPNP_E_SOCKET_ERROR;
}
#endif /* __FreeBSD__ */
#endif /* BSD */
memset( (void *)&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
ssdpAddr.sin_family = AF_INET;