Very rough first start, not even everything added
This commit is contained in:
commit
af3619d4fa
88 changed files with 24251 additions and 0 deletions
154
StreamingProxy.tproj/get_opt.c
Normal file
154
StreamingProxy.tproj/get_opt.c
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* get_opt.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#if defined(mac)
|
||||
#include <types.h>
|
||||
#endif
|
||||
|
||||
int get_opt(int argc, char *argv[], char *optList);
|
||||
|
||||
char *optarg = NULL;
|
||||
char *whatOption = NULL;
|
||||
int currentOpt = 0;
|
||||
int optind = 1;
|
||||
extern char gOptionsChar;
|
||||
|
||||
/* compareOptionString takes an option parameter with the following format:
|
||||
* -REQuired : the characters in CAPS are required to match.
|
||||
*/
|
||||
static int compareOptionString(char *option, char *compareit) {
|
||||
int i, l1, l2;
|
||||
|
||||
l1 = strlen(option);
|
||||
l2 = strlen(compareit);
|
||||
for (i=0; i<l2; i++) {
|
||||
if (option[i] == '\0')
|
||||
return -1; /* option < compareit */
|
||||
if (tolower(option[i]) == tolower(compareit[i])) {
|
||||
}
|
||||
else {
|
||||
if (option[i] > compareit[i])
|
||||
return 1; /* option > compareit */
|
||||
else
|
||||
return -1; /* option < compareit */
|
||||
}
|
||||
}
|
||||
/* if we got here, all of the characters in compareit are in option. */
|
||||
/* now we've got to check if there are any more required characters. */
|
||||
if (l1 > l2) { /* only need to check if option is longer than compareit */
|
||||
if (option[l2] == toupper(option[l2]))
|
||||
return 1; /* there was an additional character[s] needed. */
|
||||
}
|
||||
|
||||
/* if we got here, then all is hunky dory and we got the required stuff. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_opt(int argc, char *argv[], char *optList) {
|
||||
char option[256];
|
||||
int l, i, c, opt;
|
||||
|
||||
currentOpt = optind;
|
||||
optind++;
|
||||
if (currentOpt >= argc) {
|
||||
return EOF;
|
||||
}
|
||||
optarg = NULL;
|
||||
whatOption = argv[currentOpt];
|
||||
|
||||
if (whatOption[0] != gOptionsChar) {
|
||||
optarg = whatOption;
|
||||
return 0;
|
||||
}
|
||||
l = strlen(optList);
|
||||
i = 1;
|
||||
c = 0;
|
||||
opt = 1;
|
||||
option[c++] = gOptionsChar;
|
||||
while (i<=l) {
|
||||
if (optList[i] == gOptionsChar) {
|
||||
option[c++] = '\0';
|
||||
// if (strncasecmp(option, whatOption, strlen(whatOption)) == 0)
|
||||
if (compareOptionString(option, whatOption) == 0)
|
||||
// return opt;
|
||||
return option[1];
|
||||
c = 1; // reset option string to '-' since we've just seen it
|
||||
opt++; // check next option
|
||||
}
|
||||
else if (optList[i] == ':') {
|
||||
option[c++] = '\0';
|
||||
// if (strncasecmp(option, whatOption, strlen(whatOption)) == 0) {
|
||||
if (compareOptionString(option, whatOption) == 0) {
|
||||
currentOpt++; optind++;
|
||||
optarg = argv[currentOpt];
|
||||
// return opt;
|
||||
return option[1];
|
||||
}
|
||||
c = 1; // reset option string to '-'
|
||||
opt++; // check next option
|
||||
i++; // pass over the :
|
||||
if (optList[i] == gOptionsChar) {
|
||||
; // this is where we want to be
|
||||
}
|
||||
else if (optList[i] == '\0') {
|
||||
// return EOF; // this was the last option to check
|
||||
return 0; // this was the last option to check
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Malformed getopt string '%s': character %d is '%c' was expecting %c\n", optList, i, optList[i], gOptionsChar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if (optList[i] == '\0') {
|
||||
option[c++] = '\0';
|
||||
// if (strncasecmp(option, whatOption, strlen(whatOption)) == 0) {
|
||||
if (compareOptionString(option, whatOption) == 0) {
|
||||
// return opt;
|
||||
return option[1];
|
||||
}
|
||||
optarg = argv[currentOpt];
|
||||
// return EOF; // didn't find anything, return EOF
|
||||
return 0; // didn't find anything, return EOF
|
||||
}
|
||||
else {
|
||||
option[c++] = optList[i];
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
optarg = argv[currentOpt];
|
||||
return 0;
|
||||
}
|
||||
|
42
StreamingProxy.tproj/get_opt.h
Normal file
42
StreamingProxy.tproj/get_opt.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* get_opt.h
|
||||
*
|
||||
|
||||
*/
|
||||
#ifndef __GETOPT_H__
|
||||
#define __GETOPT_H__
|
||||
|
||||
extern char *optarg;
|
||||
extern char *whatOption;
|
||||
extern int currentOpt;
|
||||
extern int optind;
|
||||
|
||||
int get_opt(int argc, char *argv[], char *optList);
|
||||
|
||||
#endif
|
||||
|
1983
StreamingProxy.tproj/proxy.c
Normal file
1983
StreamingProxy.tproj/proxy.c
Normal file
File diff suppressed because it is too large
Load diff
167
StreamingProxy.tproj/proxy.h
Normal file
167
StreamingProxy.tproj/proxy.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* proxy.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PROXY_H__
|
||||
#define __PROXY_H__
|
||||
|
||||
#include "shared_udp.h"
|
||||
/**********************************************/
|
||||
enum {
|
||||
stIdle,
|
||||
stError,
|
||||
|
||||
stRecvClientCommand,
|
||||
stWaitingForIPAddress,
|
||||
stParseClientCommand,
|
||||
stSendClientResponse,
|
||||
stServerTransactionSend,
|
||||
stServerTransactionRecv,
|
||||
stClientShutdown,
|
||||
stServerShutdown,
|
||||
stBadServerName,
|
||||
stCantConnectToServer,
|
||||
stDone
|
||||
}; // rtsp session states
|
||||
|
||||
enum {
|
||||
ttNone,
|
||||
ttDescribe,
|
||||
ttSetup,
|
||||
ttPlay,
|
||||
ttPause,
|
||||
ttStop,
|
||||
ttTeardown,
|
||||
ttOptions,
|
||||
ttAnnounce,
|
||||
ttRedirect,
|
||||
ttGetParameter,
|
||||
ttSetParameter
|
||||
}; // rtsp command types
|
||||
|
||||
enum {
|
||||
kPermissionDenied,
|
||||
kTooManyUsers,
|
||||
kServerNotFound,
|
||||
kUnknownError
|
||||
}; // refusal type
|
||||
|
||||
typedef struct {
|
||||
char *cmd;
|
||||
int type;
|
||||
} t_cmd_map;
|
||||
|
||||
#define MAX_TRACKS 32
|
||||
|
||||
typedef struct {
|
||||
int ID;
|
||||
shok *RTP_S2P;
|
||||
shok *RTCP_S2P;
|
||||
shok *RTP_P2C;
|
||||
shok *RTCP_P2C;
|
||||
int ClientRTPPort;
|
||||
int ServerRTPPort;
|
||||
trans_pb RTP_S2C_tpb;
|
||||
trans_pb RTCP_S2C_tpb;
|
||||
trans_pb RTCP_C2S_tpb;
|
||||
} track_info;
|
||||
|
||||
/* This size will fit nicely in a standard ethernet frame */
|
||||
#define RTSP_SESSION_BUF_SIZE 4096
|
||||
|
||||
typedef struct rtsp_session {
|
||||
struct rtsp_session *next;
|
||||
int die;
|
||||
int newSession;
|
||||
int client_skt;
|
||||
int client_ip;
|
||||
char *server_address;
|
||||
int server_skt;
|
||||
int server_interface_addr;
|
||||
int client_interface_addr;
|
||||
int server_ip;
|
||||
int server_port;
|
||||
int server_skt_pending_connection;
|
||||
int state;
|
||||
int transaction_type;
|
||||
char *sessionID;
|
||||
|
||||
int cur_trk;
|
||||
int numTracks;
|
||||
track_info trk[MAX_TRACKS];
|
||||
|
||||
char cinbuf[RTSP_SESSION_BUF_SIZE];
|
||||
int amtInClientInBuffer;
|
||||
char coutbuf[RTSP_SESSION_BUF_SIZE];
|
||||
int amtInClientOutBuffer;
|
||||
char sinbuf[RTSP_SESSION_BUF_SIZE];
|
||||
int amtInServerInBuffer;
|
||||
char soutbuf[RTSP_SESSION_BUF_SIZE];
|
||||
int amtInServerOutBuffer;
|
||||
int totalContentLength;
|
||||
int haveParsedServerReplyHeaders;
|
||||
int contentLength;
|
||||
char* responseBodyP;
|
||||
|
||||
int tempIP;
|
||||
} rtsp_session;
|
||||
|
||||
typedef struct subnet_allow {
|
||||
struct subnet_allow *next;
|
||||
int ip;
|
||||
int range;
|
||||
} subnet_allow;
|
||||
|
||||
typedef struct rtsp_listener {
|
||||
struct rtsp_listener *next;
|
||||
int port;
|
||||
int skt;
|
||||
} rtsp_listener;
|
||||
|
||||
/**********************************************/
|
||||
int service_listeners();
|
||||
int service_sessions();
|
||||
|
||||
void add_rtsp_port_listener(int address,int port);
|
||||
void cleanup_listeners(void);
|
||||
void answer_new_connection(rtsp_listener *listener);
|
||||
void add_session(rtsp_session *session);
|
||||
void remove_session(rtsp_session *session);
|
||||
rtsp_session *new_session(void);
|
||||
void cleanup_sessions(void);
|
||||
void cleanup_session(rtsp_session *session);
|
||||
void service_session(rtsp_session *session);
|
||||
void service_session_rtp(rtsp_session *session);
|
||||
void read_config(void);
|
||||
void add_allow_subnet(int ip, int range);
|
||||
bool allow_ip(int ip);
|
||||
void send_rtsp_error(int skt, int refusal);
|
||||
|
||||
#endif // __PROXY_H__
|
||||
|
166
StreamingProxy.tproj/proxy_plat.h
Normal file
166
StreamingProxy.tproj/proxy_plat.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* proxy_plat.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _PLAT_H_
|
||||
#define _PLAT_H_
|
||||
|
||||
/**********************************************/
|
||||
#define bool char
|
||||
#if !defined(mac)
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
#if !defined(WIN32)
|
||||
#define INVALID_SOCKET -1
|
||||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
/**********************************************/
|
||||
#if defined(WIN32)
|
||||
#define EACCES WSAEACCES
|
||||
#define EINTR WSAEINTR
|
||||
#define EAGAIN WSAEWOULDBLOCK /* good enough? */
|
||||
#define EPIPE WSAESHUTDOWN /* good enough? */
|
||||
#define ENOTCONN WSAENOTCONN
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#define EISCONN WSAEISCONN
|
||||
#define EINPROGRESS WSAEINPROGRESS
|
||||
#define EALREADY WSAEALREADY
|
||||
#include "WINSOCK.H"
|
||||
#elif defined(mac)
|
||||
#define EACCES kEACCESErr
|
||||
#define EPIPE kEPIPEErr
|
||||
#define EINTR kEINTRErr
|
||||
#define EAGAIN kEAGAINErr
|
||||
#define ENOTCONN kENOTCONNErr
|
||||
#define ECONNRESET kECONNRESETErr
|
||||
#define EISCONN kEISCONNErr
|
||||
#define EINPROGRESS kEINPROGRESSErr
|
||||
#define EALREADY kEALREADYErr
|
||||
#endif
|
||||
|
||||
/**********************************************/
|
||||
#define MSEC_PER_SEC 1000
|
||||
#define USEC_PER_SEC 1000000
|
||||
#define USEC_PER_MSEC 1000
|
||||
#define timer_sub(ntime,subtime,eqtime) \
|
||||
if ((subtime).tv_usec > (ntime).tv_usec) { \
|
||||
(eqtime).tv_sec = ((ntime).tv_sec - 1) - (subtime).tv_sec; \
|
||||
(eqtime).tv_usec = (ntime).tv_usec + USEC_PER_SEC - \
|
||||
(subtime).tv_usec; \
|
||||
} \
|
||||
else { \
|
||||
(eqtime).tv_sec = (ntime).tv_sec - (subtime).tv_sec; \
|
||||
(eqtime).tv_usec = (ntime).tv_usec - (subtime).tv_usec; \
|
||||
}
|
||||
|
||||
|
||||
extern char *gConfigFilePath;
|
||||
extern char *gOptionsString;
|
||||
extern char gOptionsChar;
|
||||
|
||||
typedef struct stats_chunk {
|
||||
unsigned long elapsedSeconds;
|
||||
unsigned long bpsReceived;
|
||||
unsigned long bpsSent;
|
||||
unsigned long ppsReceived;
|
||||
unsigned long ppsSent;
|
||||
unsigned long totalPacketsReceived;
|
||||
unsigned long totalPacketsSent;
|
||||
unsigned long numClients;
|
||||
unsigned long numPorts;
|
||||
float percentLostPackets;
|
||||
} stats_chunk;
|
||||
|
||||
|
||||
void daemonize(void);
|
||||
int init_network(void);
|
||||
int term_network(void);
|
||||
int init_ui(void);
|
||||
int service_ui(int sleep_ticks);
|
||||
|
||||
void sleep_milliseconds(int ms);
|
||||
time_t microseconds();
|
||||
#define kPENDING_ADDRESS -2
|
||||
int name_to_ip_num(char *name, int *ip_num, int async);
|
||||
int get_remote_address(int skt, int *port);
|
||||
int get_local_address(int skt, int *port);
|
||||
int get_local_ip_address(void);
|
||||
bool isReadable(int fd);
|
||||
bool isWritable(int fd);
|
||||
|
||||
int new_socket_udp(void);
|
||||
int new_socket_tcp(int is_listener);
|
||||
void close_socket(int skt);
|
||||
void set_socket_reuse_address(int skt);
|
||||
void set_socket_max_buf(int skt);
|
||||
void make_socket_nonblocking(int skt);
|
||||
int bind_socket_to_address(int skt, int address, int port, int is_listener);
|
||||
int listen_to_socket(int skt);
|
||||
int call_is_waiting(int skt, int *incoming_skt);
|
||||
int accept_connection(int from, int *to);
|
||||
int get_interface_addr(int skt);
|
||||
#if DO_ASYNC
|
||||
pascal void conn_finished_proc(void* contextPtr, OTEventCode code, OTResult /*result*/, void* /*cookie*/);
|
||||
int connect_to_address(void *context, OTNotifyProcPtr proc, int skt, int address, int port);
|
||||
#else
|
||||
int connect_to_address(int skt, int address, int port);
|
||||
#endif
|
||||
|
||||
int tcp_data_ready(int skt);
|
||||
|
||||
int recv_udp(int skt, char *buf, int amt, int *fromAddress, int *fromPort);
|
||||
int send_udp(int skt, char *buf, int amt, int address, int port);
|
||||
int recv_tcp(int skt, char *buf, int amt);
|
||||
int send_tcp(int skt, char *buf, int amt);
|
||||
|
||||
// int make_udp_port_pair(int *socket1, int *socket2);
|
||||
|
||||
int GetLastSocketError(int skt);
|
||||
void DoStats(stats_chunk *stats);
|
||||
|
||||
#if defined(mac) || defined(WIN32)
|
||||
extern char gLastErrorString[256];
|
||||
#define ErrorString(a) sprintf(gLastErrorString, a)
|
||||
#define ErrorString1(a,b) sprintf(gLastErrorString, a, b)
|
||||
#define ErrorStringS(a,b) sprintf(gLastErrorString, a, b)
|
||||
#define DebugString(a) printf(a "\n")
|
||||
#define DebugString1(a,b) printf(a "\n", b)
|
||||
#define DebugStringS(a,b) printf(a "\n", b)
|
||||
#else
|
||||
void ErrorString(char *string);
|
||||
void ErrorString1(char *string, int d);
|
||||
void ErrorStringS(char *string, char *arg);
|
||||
#define DebugString(a) printf(a "\n")
|
||||
#define DebugString1(a,b) printf(a "\n", b)
|
||||
#define DebugStringS(a,b) printf(a "\n", b)
|
||||
#endif
|
||||
#endif // _PLAT_H_
|
||||
|
579
StreamingProxy.tproj/proxy_unix.c
Normal file
579
StreamingProxy.tproj/proxy_unix.c
Normal file
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
proxy_unix.c
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "proxy_plat.h"
|
||||
|
||||
#if USE_THREAD
|
||||
#include "pthread.h"
|
||||
#endif
|
||||
|
||||
#include "../defaultPaths.h"
|
||||
|
||||
char *gConfigFilePath = DEFAULTPATHS_ETC_DIR "streamingproxy.conf";
|
||||
|
||||
char *gOptionsString = "-c:-p:-d-D-v-h-s-x-i:";
|
||||
char gOptionsChar = '-';
|
||||
|
||||
extern int gMaxPorts;
|
||||
extern float gDropPercent;
|
||||
|
||||
/**********************************************/
|
||||
int init_network()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
#define kKILL_THREAD -3
|
||||
int term_network()
|
||||
{
|
||||
int send = kKILL_THREAD;
|
||||
name_to_ip_num("", &send, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
typedef struct ghpb_rec {
|
||||
char name[256];
|
||||
int *result;
|
||||
} ghpb_rec, *ghpb;
|
||||
|
||||
#if USE_THREAD
|
||||
void *gethostthread(void *param)
|
||||
{
|
||||
struct hostent *hent;
|
||||
ghpb pb = (ghpb)param;
|
||||
int id;
|
||||
pthread_t tid;
|
||||
int tryCount = 0;
|
||||
|
||||
if (*pb->result == kKILL_THREAD)
|
||||
exit(0);
|
||||
tid = pthread_self();
|
||||
again:
|
||||
hent = gethostbyname(pb->name);
|
||||
if (hent == NULL) do
|
||||
{
|
||||
tryCount ++;
|
||||
if (h_errno == TRY_AGAIN)
|
||||
{ if (tryCount < 10)
|
||||
goto again;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
*pb->result = -1;
|
||||
pthread_exit(NULL);
|
||||
} while(0);
|
||||
id = ntohl(((struct in_addr *)(hent->h_addr_list[0]))->s_addr);
|
||||
*pb->result = id;
|
||||
free(pb);
|
||||
pthread_exit(NULL);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
/**********************************************/
|
||||
int name_to_ip_num(char *name, int *ip, int async)
|
||||
{
|
||||
int ret;
|
||||
struct in_addr addr;
|
||||
int tryAgain = 0;
|
||||
#if USE_THREAD
|
||||
ghpb pb = NULL;
|
||||
pthread_t tid;
|
||||
#endif
|
||||
struct hostent *hent;
|
||||
|
||||
if (check_IP_cache(name, &ret) != -1)
|
||||
{
|
||||
*ip = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if USE_THREAD
|
||||
if (async)
|
||||
{
|
||||
*ip = kPENDING_ADDRESS;
|
||||
pb = (ghpb)malloc(sizeof(ghpb_rec));
|
||||
strcpy(pb->name, name);
|
||||
pb->result = ip;
|
||||
pthread_create(&tid, NULL, gethostthread, (void*)pb);
|
||||
pthread_detach(tid);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
again:
|
||||
|
||||
tryAgain ++;
|
||||
if ( inet_aton( name, &addr ) )
|
||||
{ *ip = ntohl( addr.s_addr );
|
||||
add_to_IP_cache(name, *ip );
|
||||
return 0;
|
||||
}
|
||||
|
||||
hent = gethostbyname(name);
|
||||
if (hent == NULL) {
|
||||
if (h_errno == TRY_AGAIN)
|
||||
if (tryAgain < 10)
|
||||
goto again;
|
||||
add_to_IP_cache(name, -1);
|
||||
return -1;
|
||||
}
|
||||
*ip = ntohl(((struct in_addr *) (hent->h_addr_list[0]))->s_addr);
|
||||
add_to_IP_cache(name, *ip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************/
|
||||
int get_remote_address(int skt, int *port)
|
||||
{
|
||||
#if !defined(sparc) && !defined(SGI) && !defined(WIN32)
|
||||
unsigned
|
||||
#endif
|
||||
int nAddrSize = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in remAddr;
|
||||
int status;
|
||||
remAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
status = getpeername(skt, (struct sockaddr*)&remAddr, &nAddrSize);
|
||||
if (status >= 0)
|
||||
{
|
||||
if (port)
|
||||
*port = ntohs(remAddr.sin_port);
|
||||
return ntohl(remAddr.sin_addr.s_addr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int get_local_address(int skt, int *port) {
|
||||
#if !defined(sparc) && !defined(SGI) && !defined(WIN32)
|
||||
unsigned
|
||||
#endif
|
||||
int nAddrSize = sizeof(struct sockaddr_in);
|
||||
struct sockaddr_in remAddr;
|
||||
int status;
|
||||
remAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
status = getsockname(skt, (struct sockaddr*)&remAddr, &nAddrSize);
|
||||
if (status >= 0)
|
||||
{
|
||||
if (port)
|
||||
*port = ntohs(remAddr.sin_port);
|
||||
return ntohl(remAddr.sin_addr.s_addr);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
static int __local_ip_address = -1;
|
||||
|
||||
int get_local_ip_address()
|
||||
{
|
||||
char buf[256];
|
||||
struct hostent *hent;
|
||||
int tryCount = 0;
|
||||
|
||||
if (__local_ip_address != -1)
|
||||
return __local_ip_address;
|
||||
|
||||
if (gethostname(buf, 256) < 0)
|
||||
return -1;
|
||||
again:
|
||||
tryCount ++;
|
||||
hent = gethostbyname(buf);
|
||||
if (hent == NULL)
|
||||
{ if (h_errno == TRY_AGAIN)
|
||||
{ if (tryCount < 10)
|
||||
{
|
||||
goto again;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
__local_ip_address = ntohl(((struct in_addr *)hent->h_addr)->s_addr);
|
||||
return __local_ip_address;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void make_socket_nonblocking(int socket)
|
||||
{
|
||||
int flag;
|
||||
flag = fcntl(socket, F_GETFL, 0);
|
||||
fcntl(socket, F_SETFL, flag | O_NONBLOCK);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void sleep_milliseconds(int ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = ms / 1000;
|
||||
tv.tv_usec = (ms - (tv.tv_sec * 1000) ) * 1000;
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
time_t microseconds()
|
||||
{
|
||||
static bool us_initted = false;
|
||||
static struct timeval us_time_zero;
|
||||
struct timeval tv, t;
|
||||
struct timezone tz;
|
||||
|
||||
gettimeofday(&tv, &tz);
|
||||
if (us_initted == false)
|
||||
{
|
||||
us_initted = true;
|
||||
us_time_zero = tv;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer_sub(tv, us_time_zero, t);
|
||||
return (t.tv_sec * USEC_PER_SEC + t.tv_usec);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
bool isReadable(int fd)
|
||||
{
|
||||
|
||||
/* causes crash fd_set is wrong size if num users > 255
|
||||
// not needed anyway
|
||||
|
||||
fd_set set;
|
||||
struct timeval tv;
|
||||
int err;
|
||||
|
||||
if (fd == INVALID_SOCKET)
|
||||
return false;
|
||||
|
||||
tv.tv_sec = 0; tv.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&set);
|
||||
|
||||
FD_SET(fd, &set);
|
||||
|
||||
err = select(fd+1, &set, NULL, NULL, &tv);
|
||||
if (err > 0)
|
||||
if (FD_ISSET(fd, &set))
|
||||
return true;
|
||||
return false;
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
bool isWritable(int fd)
|
||||
{
|
||||
/* causes crash fd_set is wrong size if num users > 255
|
||||
// not needed anyway
|
||||
|
||||
fd_set set;
|
||||
struct timeval tv;
|
||||
int err;
|
||||
|
||||
if (fd == INVALID_SOCKET)
|
||||
return false;
|
||||
tv.tv_sec = 0; tv.tv_usec = 0;
|
||||
FD_ZERO(&set);
|
||||
FD_SET(fd, &set);
|
||||
err = select(fd+1, NULL, &set, NULL, &tv);
|
||||
if (err > 0)
|
||||
if (FD_ISSET(fd, &set))
|
||||
return true;
|
||||
return false;
|
||||
*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int new_socket_udp(void)
|
||||
{
|
||||
int ret;
|
||||
ret = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
gMaxPorts++;
|
||||
set_socket_max_buf(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int new_socket_tcp(int is_listener)
|
||||
{
|
||||
int ret;
|
||||
ret = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
gMaxPorts++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void set_socket_reuse_address(int skt)
|
||||
{
|
||||
int i = 1;
|
||||
setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (char*)&i, sizeof(i));
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void set_socket_max_buf(int skt)
|
||||
{
|
||||
int i = 1;
|
||||
unsigned int len;
|
||||
len = sizeof(i);
|
||||
getsockopt(skt, SOL_SOCKET, SO_SNDBUF, (char*)&i, &len);
|
||||
/*fprintf(stderr, "sndbuf for socket %d was %d\n", skt, i);*/
|
||||
i *= 2;
|
||||
setsockopt(skt, SOL_SOCKET, SO_SNDBUF, (char*)&i, len);
|
||||
getsockopt(skt, SOL_SOCKET, SO_SNDBUF, (char*)&i, &len);
|
||||
/*fprintf(stderr, "sndbuf for socket %d is now %d\n", skt, i);*/
|
||||
getsockopt(skt, SOL_SOCKET, SO_RCVBUF, (char*)&i, &len);
|
||||
/*fprintf(stderr, "rcvbuf for socket %d was %d\n", skt, i);*/
|
||||
i *= 2;
|
||||
setsockopt(skt, SOL_SOCKET, SO_RCVBUF, (char*)&i, len);
|
||||
getsockopt(skt, SOL_SOCKET, SO_RCVBUF, (char*)&i, &len);
|
||||
/*fprintf(stderr, "rcvbuf for socket %d is now %d\n", skt, i);*/
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int bind_socket_to_address(int skt, int address, int port, int is_listener)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (address == -1)
|
||||
address = INADDR_ANY;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = htonl(address);
|
||||
return bind(skt, (struct sockaddr*)&sin, sizeof(sin));
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void close_socket(int skt)
|
||||
{
|
||||
if (skt != INVALID_SOCKET)
|
||||
{
|
||||
gMaxPorts--;
|
||||
close(skt);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int listen_to_socket(int skt)
|
||||
{
|
||||
return listen(skt, 5);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int call_is_waiting(int skt, int *incoming_skt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = isReadable(skt);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
*incoming_skt = accept(skt, 0, 0);
|
||||
|
||||
if (*incoming_skt <= 0)
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
else
|
||||
gMaxPorts++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int accept_connection(int from, int *to)
|
||||
{
|
||||
// return accept(from, 0, 0);
|
||||
return *to;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int connect_to_address(int skt, int address, int port)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = htonl(address);;
|
||||
return connect(skt, (struct sockaddr*)&sin, sizeof(sin));
|
||||
}
|
||||
|
||||
int get_interface_addr(int skt)
|
||||
{
|
||||
int err = 0;
|
||||
struct sockaddr_in localAddr;
|
||||
unsigned int len = sizeof(localAddr);
|
||||
memset(&localAddr, 0, sizeof(localAddr));
|
||||
|
||||
err = getsockname(skt, (struct sockaddr*)&localAddr, &len);
|
||||
return ntohl(localAddr.sin_addr.s_addr);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int recv_udp(int socket, char *buf, int amt, int *fromip, int *fromport)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int ret;
|
||||
unsigned int len;
|
||||
|
||||
len = sizeof(sin);
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
ret = recvfrom(socket, buf, (size_t) amt, 0, (struct sockaddr*)&sin, &len);
|
||||
if (ret != -1) {
|
||||
if (fromip)
|
||||
*fromip = ntohl(sin.sin_addr.s_addr);
|
||||
if (fromport)
|
||||
*fromport = ntohs(sin.sin_port);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int send_udp(int skt, char *buf, int amt, int address, int port)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = htonl(address);
|
||||
return sendto(skt, buf, (size_t) amt, 0, (struct sockaddr*)&sin, sizeof(sin));
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int recv_tcp(int socket, char *buf, int amt)
|
||||
{
|
||||
return read(socket, buf, (size_t) amt);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int send_tcp(int socket, char *buf, int amt)
|
||||
{
|
||||
return write(socket, buf, (size_t) amt);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int GetLastSocketError(int skt)
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int init_ui()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int service_ui(int sleep_time)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void DoStats(stats_chunk *stats)
|
||||
{
|
||||
printf("\033[2J\033[H");
|
||||
printf("Elapsed Time (seconds) : %lu\n", stats->elapsedSeconds);
|
||||
printf("Number of clients : %lu\n", stats->numClients);
|
||||
printf("bps Received : %lu\n", stats->bpsReceived);
|
||||
printf("bps Sent : %lu\n", stats->bpsSent);
|
||||
printf("Total Packets Received : %lu\n", stats->totalPacketsReceived);
|
||||
printf("Total Packets Sent : %lu\n", stats->totalPacketsSent);
|
||||
printf("pps Received : %lu\n", stats->ppsReceived);
|
||||
printf("pps Sent : %lu\n", stats->ppsSent);
|
||||
printf("number of ports used : %lu\n", stats->numPorts);
|
||||
printf("packet loss percent : %f\n", stats->percentLostPackets);
|
||||
printf("force drop percent : %f\n",gDropPercent);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void ErrorString(char *string)
|
||||
{
|
||||
fprintf(stderr, string);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void ErrorString1(char *string, int d)
|
||||
{
|
||||
fprintf(stderr, string, d);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void ErrorStringS(char *string, char *arg)
|
||||
{
|
||||
fprintf(stderr, string, arg);
|
||||
}
|
||||
|
||||
void daemonize()
|
||||
{
|
||||
switch (fork()) {
|
||||
case -1: /* error */
|
||||
fprintf(stderr, "can't daemonize!\n");
|
||||
case 0: /* child */
|
||||
break;
|
||||
default: /* parent */
|
||||
exit(0);
|
||||
}
|
||||
}
|
474
StreamingProxy.tproj/shared_udp.c
Normal file
474
StreamingProxy.tproj/shared_udp.c
Normal file
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: shared_udp.c
|
||||
Contains: UDP Sockets implementation with shared ports
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(unix)
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/resource.h>
|
||||
#include <signal.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/socket.h>
|
||||
#elif defined(win32)
|
||||
#include "WINSOCK.H"
|
||||
#include "regex.h"
|
||||
#elif defined(mac)
|
||||
#include <MacTypes.h>
|
||||
#include "OpenTransport.h"
|
||||
#endif
|
||||
|
||||
#include "shared_udp.h"
|
||||
#include "proxy_plat.h"
|
||||
|
||||
#if DEBUG
|
||||
#define DEBUGPRINT(x) printf x
|
||||
#else
|
||||
#define DEBUGPRINT(x)
|
||||
#endif
|
||||
|
||||
/**********************************************/
|
||||
shok *gShokList = NULL;
|
||||
|
||||
/**********************************************/
|
||||
ipList *find_ip_in_list(ipList *list, int ip)
|
||||
{
|
||||
ipList *cur = list;
|
||||
|
||||
DEBUGPRINT(( "-- -- looking for IP %x in IP list\n", ip));
|
||||
while (cur) {
|
||||
DEBUGPRINT(("-- -- vs. %x\n", cur->ip));
|
||||
if (cur->ip == ip) {
|
||||
DEBUGPRINT(("-- -- FOUND\n"));
|
||||
return cur;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
DEBUGPRINT(("-- -- NOT FOUND\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int add_ip_to_list(ipList **list, int ip)
|
||||
{
|
||||
ipList *newEl;
|
||||
|
||||
newEl = (ipList*)malloc(sizeof(ipList));
|
||||
if (!newEl)
|
||||
return false;
|
||||
newEl->ip = ip;
|
||||
newEl->what_to_do = NULL;
|
||||
newEl->what_to_do_it_with = NULL;
|
||||
newEl->next = *list;
|
||||
*list = newEl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int remove_ip_from_list(ipList **list, int ip)
|
||||
{
|
||||
ipList *last, *theEl = *list;
|
||||
|
||||
if (theEl->ip == ip) {
|
||||
*list = theEl->next;
|
||||
free(theEl);
|
||||
return true;
|
||||
}
|
||||
|
||||
last = theEl;
|
||||
theEl = theEl->next;
|
||||
while (theEl) {
|
||||
if (theEl->ip == ip) {
|
||||
last->next = theEl->next;
|
||||
free(theEl);
|
||||
return true;
|
||||
}
|
||||
last = theEl;
|
||||
theEl = theEl->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
shok *find_available_shok(int fromIP, int toIP, int withSib)
|
||||
{
|
||||
shok *cur = gShokList;
|
||||
|
||||
while (cur) {
|
||||
DEBUGPRINT(("-- looking for IP %x in shok %p\n", toIP, cur));
|
||||
if (find_ip_in_list(cur->ips, toIP) == NULL) {
|
||||
if (withSib) {
|
||||
DEBUGPRINT(("-- looking for IP %x in SIB shok %p\n", toIP, cur->sib));
|
||||
if (find_ip_in_list(cur->sib->ips, toIP) == NULL)
|
||||
return cur;
|
||||
}
|
||||
else
|
||||
return cur;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int add_ips_to_shok(shok *theShok, int fromIP, int toIP, int withSib)
|
||||
{
|
||||
add_ip_to_list(&(theShok->ips), toIP);
|
||||
if (withSib)
|
||||
add_ip_to_list(&(theShok->sib->ips), toIP);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
static int gUDPPortMin = 4000;
|
||||
static int gUDPPortMax = 65536;
|
||||
#define sInvalidPort -1
|
||||
static int gNextPort = sInvalidPort;
|
||||
|
||||
void set_udp_port_min_and_max(int min, int max)
|
||||
{
|
||||
gUDPPortMin = min;
|
||||
gUDPPortMax = max;
|
||||
if (gUDPPortMin & 0x1)
|
||||
gUDPPortMin++;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int remove_shok(shok *theShok, int withSib)
|
||||
{
|
||||
shok *cur = NULL, *last;
|
||||
|
||||
cur = gShokList;
|
||||
if (cur == theShok) {
|
||||
gShokList = cur->next;
|
||||
goto doSib;
|
||||
}
|
||||
|
||||
last = cur;
|
||||
cur = cur->next;
|
||||
while (cur) {
|
||||
if (cur == theShok) {
|
||||
last->next = cur->next;
|
||||
goto doSib;
|
||||
}
|
||||
last = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
return false;
|
||||
|
||||
doSib:
|
||||
if (cur->sib)
|
||||
cur->sib->sib = NULL;
|
||||
if (withSib && cur->sib)
|
||||
remove_shok(cur->sib, false);
|
||||
|
||||
{
|
||||
ipList *ipn, *ipl = cur->ips;
|
||||
while (ipl) {
|
||||
ipn = ipl->next;
|
||||
free(ipn);
|
||||
ipl = ipn;
|
||||
}
|
||||
}
|
||||
close_socket(cur->socket);
|
||||
free(cur);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
void remove_shok_ref(shok *theShok, int fromIP, int toIP, int withSib)
|
||||
{
|
||||
remove_ip_from_list(&(theShok->ips), toIP);
|
||||
if (withSib)
|
||||
remove_ip_from_list(&(theShok->sib->ips), toIP);
|
||||
if (theShok->sib->ips == NULL)
|
||||
remove_shok(theShok->sib, false);
|
||||
if (theShok->ips == NULL)
|
||||
remove_shok(theShok, false);
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
shok *make_new_shok(int fromIP, int toIP, int withSib)
|
||||
{
|
||||
shok *theShok1 = NULL, *theShok2 = NULL;
|
||||
int skt1 = INVALID_SOCKET, skt2 = INVALID_SOCKET;
|
||||
int port1 = sInvalidPort;
|
||||
int port2 = sInvalidPort;
|
||||
|
||||
theShok1 = (shok*)malloc(sizeof(shok));
|
||||
if (!theShok1)
|
||||
goto bail_error;
|
||||
if (withSib) {
|
||||
theShok2 = (shok*)malloc(sizeof(shok));
|
||||
if (!theShok2)
|
||||
goto bail_error;
|
||||
}
|
||||
|
||||
if (gNextPort == -1)
|
||||
gNextPort = gUDPPortMin;
|
||||
retry:
|
||||
if ((skt1 = new_socket_udp()) == SOCKET_ERROR)
|
||||
goto bail_error;
|
||||
if (skt1 == 0) {
|
||||
if (GetLastSocketError(skt1) == EINPROGRESS || GetLastSocketError(skt1) == EAGAIN)
|
||||
goto retry;
|
||||
else
|
||||
goto bail_error;
|
||||
}
|
||||
do {
|
||||
if ((gNextPort & 0x1) && withSib)
|
||||
gNextPort++;
|
||||
if (gNextPort > gUDPPortMax)
|
||||
gNextPort = gUDPPortMin;
|
||||
} while (bind_socket_to_address(skt1, fromIP, port1 = gNextPort++, false) != 0);
|
||||
|
||||
if (withSib) {
|
||||
retry_rtcp:
|
||||
if ((skt2 = new_socket_udp()) == SOCKET_ERROR)
|
||||
goto bail_error;
|
||||
if (skt2 == 0) {
|
||||
if (GetLastSocketError(skt2) == EINPROGRESS || GetLastSocketError(skt2) == EAGAIN)
|
||||
goto retry_rtcp;
|
||||
else
|
||||
goto bail_error;
|
||||
}
|
||||
if (bind_socket_to_address(skt2, fromIP, port2 = gNextPort++, false) != 0) {
|
||||
close_socket(skt1);
|
||||
close_socket(skt2);
|
||||
skt1 = INVALID_SOCKET;
|
||||
skt2 = INVALID_SOCKET;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
make_socket_nonblocking(skt1);
|
||||
theShok1->socket = skt1;
|
||||
theShok1->port = port1;
|
||||
theShok1->ips = NULL;
|
||||
|
||||
if (withSib) {
|
||||
make_socket_nonblocking(skt2);
|
||||
theShok2->socket = skt2;
|
||||
theShok2->port = port2;
|
||||
theShok2->ips = NULL;
|
||||
theShok2->sib = theShok1;
|
||||
|
||||
theShok1->sib = theShok2;
|
||||
theShok1->next = theShok2;
|
||||
theShok2->next = gShokList;
|
||||
}
|
||||
else {
|
||||
theShok1->sib = NULL;
|
||||
theShok1->next = gShokList;
|
||||
}
|
||||
|
||||
add_ips_to_shok(theShok1, fromIP, toIP, withSib);
|
||||
gShokList = theShok1;
|
||||
|
||||
return theShok1;
|
||||
|
||||
bail_error:
|
||||
printf("make_new_shok bail_error\n");
|
||||
close_socket(skt1);
|
||||
close_socket(skt2);
|
||||
if (theShok1 != NULL)
|
||||
free(theShok1);
|
||||
if (theShok2 != NULL)
|
||||
free(theShok2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int make_udp_port_pair(int fromIP, int toIP, shok **rtpSocket, shok **rtcpSocket)
|
||||
{
|
||||
shok *theShok;
|
||||
|
||||
DEBUGPRINT(("MAKE_UDP_PORT_PAIR from %x to %x\n", fromIP, toIP));
|
||||
DEBUGPRINT(("looking for available shok\n"));
|
||||
|
||||
if ((theShok = find_available_shok(fromIP, toIP, true)) != NULL) {
|
||||
DEBUGPRINT(("found available shok : SOCKET [%d] PORT [%d]\n", theShok->socket, theShok->port));
|
||||
add_ips_to_shok(theShok, fromIP, toIP, true);
|
||||
}
|
||||
else {
|
||||
theShok = make_new_shok(fromIP, toIP, true);
|
||||
DEBUGPRINT(("couldn't find shok - made new one : SOCKET [%d] PORT [%d]\n", theShok->socket, theShok->port));
|
||||
}
|
||||
|
||||
if (theShok && theShok->sib) {
|
||||
*rtpSocket = theShok;
|
||||
*rtcpSocket = theShok->sib;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int upon_receipt_from(shok *theShok, int fromIP, do_routine doThis, void *withThis)
|
||||
{
|
||||
ipList *listEl;
|
||||
DEBUGPRINT(( "UPON_RECEIPT_FROM %x do routine %p\n", fromIP, doThis));
|
||||
listEl = find_ip_in_list(theShok->ips, fromIP);
|
||||
if (!listEl)
|
||||
return -1;
|
||||
listEl->what_to_do = doThis;
|
||||
listEl->what_to_do_it_with = withThis;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
extern int gNeedsService;
|
||||
extern unsigned long gPacketsReceived;
|
||||
extern unsigned long gPacketsSent;
|
||||
extern unsigned long gBytesReceived;
|
||||
extern unsigned long gBytesSent;
|
||||
extern float gDropPercent;
|
||||
extern unsigned long gDropDelta;
|
||||
|
||||
|
||||
/**********************************************/
|
||||
int service_shoks()
|
||||
{
|
||||
shok *cur;
|
||||
char buf[2048];
|
||||
|
||||
cur = gShokList;
|
||||
while (cur) {
|
||||
do_routine doit;
|
||||
int ret, fromPort, fromIP;
|
||||
|
||||
again:
|
||||
doit = NULL;
|
||||
ret = recv_udp(cur->socket, buf, 2048, &fromIP, &fromPort);
|
||||
if (ret > 0) {
|
||||
ipList *ipl = NULL;
|
||||
|
||||
DEBUGPRINT(("Got %d bytes for %x on port %d on socket %d\n", ret, fromIP, fromPort, cur->socket));
|
||||
gBytesReceived += ret;
|
||||
gPacketsReceived++;
|
||||
ipl = find_ip_in_list(cur->ips, fromIP);
|
||||
if (ipl)
|
||||
doit = ipl->what_to_do;
|
||||
if (doit && ipl) {
|
||||
gNeedsService++;
|
||||
ret = (*doit)(ipl->what_to_do_it_with, buf, ret);
|
||||
if (ret == -1) {
|
||||
// what to do about termination, etc.
|
||||
DEBUGPRINT(("put returns error %d\n", errno));
|
||||
}
|
||||
else if (ret == 0) {
|
||||
// client/server whatever died
|
||||
if (((trans_pb*)ipl->what_to_do_it_with)->status)
|
||||
*(((trans_pb*)ipl->what_to_do_it_with)->status) = 1;
|
||||
DEBUGPRINT(("client/server died\n"));
|
||||
}
|
||||
// what to do about incomplete packet transmission
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
else if (ret < 0) {
|
||||
if (errno != 11)
|
||||
DEBUGPRINT(("recv_udp returns errno %d\n", errno));
|
||||
// what to do about termination, etc.
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int transfer_data(void *refCon, char *buf, int bufSize)
|
||||
{
|
||||
trans_pb *tpb = (trans_pb*)refCon;
|
||||
int ret;
|
||||
int isRTCP = 0;
|
||||
if (!tpb)
|
||||
return -1;
|
||||
|
||||
if (strstr(tpb->socketName,"RTCP"))
|
||||
{ //printf("shared_udp.c transfer_data %s\n",tpb->socketName);
|
||||
isRTCP = 1;
|
||||
}
|
||||
tpb->packetCount++;
|
||||
if (gDropPercent > 0.0 )
|
||||
{ int packetDropped = 0;
|
||||
//printf("transfer_data tpb->nextDropPacket=%qd tpb->packetCount=%qd\n",tpb->nextDropPacket, tpb->packetCount);
|
||||
if (tpb->packetCount == tpb->nextDropPacket)
|
||||
{ tpb->droppedPacketCount ++;
|
||||
tpb->nextDropPacket = 0;
|
||||
//printf("transfer_data tpb->droppedPacketCount=%qd tpb->packetCount=%qd\n",tpb->droppedPacketCount, tpb->packetCount);
|
||||
packetDropped = 1;
|
||||
}
|
||||
|
||||
if (tpb->nextDropPacket == 0)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
if (gDropPercent <= 50.0)
|
||||
offset = 100.0 / gDropPercent; // drop the percent packet
|
||||
else if (gDropPercent < 100.0 )
|
||||
offset = 1 + ( ( (rand() % 49) <= ( gDropPercent - 47.0) ) ? 0 : 1);// drop random 1 to 2 packets 1 == next packet or 100% 2== every other 50%
|
||||
else
|
||||
offset = 1; // 100% = drop next packet
|
||||
|
||||
tpb->nextDropPacket = tpb->packetCount + offset;
|
||||
}
|
||||
|
||||
if (packetDropped)
|
||||
return bufSize;
|
||||
|
||||
}
|
||||
|
||||
ret = send_udp(tpb->send_from->socket, buf, bufSize, tpb->send_to_ip, tpb->send_to_port);
|
||||
DEBUGPRINT(("Sent %d bytes to %x on port %d on socket %d\n",
|
||||
ret, tpb->send_to_ip, tpb->send_to_port, tpb->send_from->socket));
|
||||
if (ret > 0)
|
||||
{ gBytesSent += ret;
|
||||
gPacketsSent++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
84
StreamingProxy.tproj/shared_udp.h
Normal file
84
StreamingProxy.tproj/shared_udp.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: shared_udp.h
|
||||
Contains: udp sockets implementation with shared ports
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SHARED_UDP_H__
|
||||
#define __SHARED_UDP_H__
|
||||
|
||||
#define MAX_SOCKET_NAME 32
|
||||
|
||||
/**********************************************/
|
||||
typedef int (*do_routine)(void * refCon, char *buf, int bufSize);
|
||||
|
||||
typedef struct ipList {
|
||||
struct ipList *next;
|
||||
int ip;
|
||||
do_routine what_to_do;
|
||||
void *what_to_do_it_with;
|
||||
} ipList;
|
||||
|
||||
typedef struct shok {
|
||||
struct shok *next;
|
||||
int socket;
|
||||
int port;
|
||||
ipList *ips;
|
||||
struct shok *sib; // sibling - rtcp or rtp
|
||||
} shok;
|
||||
|
||||
typedef struct trans_pb {
|
||||
int *status; // set to 1 when needs to die
|
||||
shok *send_from;
|
||||
int send_to_ip;
|
||||
int send_to_port;
|
||||
long long int packetSendCount;
|
||||
long long int nextDropPacket;
|
||||
long long int droppedPacketCount;
|
||||
long long int packetCount;
|
||||
char socketName[MAX_SOCKET_NAME];
|
||||
|
||||
} trans_pb;
|
||||
|
||||
/**********************************************/
|
||||
ipList *find_ip_in_list(ipList *list, int ip);
|
||||
int add_ip_to_list(ipList **list, int ip);
|
||||
int remove_ip_from_list(ipList **list, int ip);
|
||||
shok *find_available_shok(int fromIP, int toIP, int withSib);
|
||||
int add_ips_to_shok(shok *theShok, int fromIP, int toIP, int withSib);
|
||||
void set_udp_port_min_and_max(int min, int max);
|
||||
int remove_shok(shok *theShok, int withSib);
|
||||
void remove_shok_ref(shok *theShok, int fromIP, int toIP, int withSib);
|
||||
shok *make_new_shok(int fromIP, int toIP, int withSib);
|
||||
int make_udp_port_pair(int fromIP, int toIP, shok **rtpSocket, shok **rtcpSocket);
|
||||
int upon_receipt_from(shok *theShok, int fromIP, do_routine doThis, void *withThis);
|
||||
int service_shoks();
|
||||
int transfer_data(void *refCon, char *buf, int bufSize);
|
||||
|
||||
#endif // __SHARED_UDP_H__
|
||||
|
273
StreamingProxy.tproj/util.c
Normal file
273
StreamingProxy.tproj/util.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* util.c
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
static char to_lower(int c);
|
||||
|
||||
/**********************************************/
|
||||
static char ip_string_buffer[20];
|
||||
char *ip_to_string(int ip) {
|
||||
sprintf(ip_string_buffer, "%d.%d.%d.%d",
|
||||
(ip & 0xff000000) >> 24, (ip & 0x00ff0000) >> 16,
|
||||
(ip & 0x0000ff00) >> 8, (ip & 0x000000ff));
|
||||
return ip_string_buffer;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
static char to_lower(int c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return ((c - 'A') + 'a');
|
||||
return c;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
char *str_dup(char *str)
|
||||
{
|
||||
char *ret;
|
||||
|
||||
ret = (char*)malloc(strlen(str)+1);
|
||||
strcpy(ret, str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int str_casecmp(char *str1, char *str2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = *str1 - *str2;
|
||||
while (*str1 && *str2 && ((ret = *str1++ - *str2++) == 0))
|
||||
;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int strn_casecmp(char *str1, char *str2, int l)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = to_lower( (char) *str1) - to_lower((char) *str2);
|
||||
while (l-- && to_lower(*str1) && to_lower(*str2) && ((ret = to_lower(*str1++) - to_lower(*str2++)) == 0))
|
||||
;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
grab a full line from input
|
||||
put into strBuff as 0 terminated
|
||||
must maintain the exact eol that the
|
||||
input string has.
|
||||
|
||||
return next position.
|
||||
*/
|
||||
|
||||
char* get_line_str( char* strBuff, char *input, int buffSize)
|
||||
{
|
||||
char *p = input;
|
||||
int sawEOLChar = 0;
|
||||
|
||||
assert( strBuff != NULL && input != NULL && buffSize > 0);
|
||||
|
||||
memset(strBuff, 0, (size_t) buffSize);
|
||||
while( *p )
|
||||
{
|
||||
assert( buffSize > 0 );
|
||||
|
||||
if ( *p == '\r' || *p == '\n' )
|
||||
{ // grab all eol chars
|
||||
sawEOLChar = 1;
|
||||
*strBuff = *p;
|
||||
strBuff++;
|
||||
buffSize--;
|
||||
|
||||
}
|
||||
else if ( sawEOLChar )
|
||||
{
|
||||
// we saw eol char(s) and now this is not one
|
||||
// that means we're done
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// grab all line chars
|
||||
*strBuff = *p;
|
||||
strBuff++;
|
||||
buffSize--;
|
||||
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
*strBuff = 0;
|
||||
|
||||
// we're not going to change the contents
|
||||
// of input, but the caller may have the right too.
|
||||
return (char*)p;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**********************************************
|
||||
|
||||
subdivide a string along the delimeter
|
||||
points in delim
|
||||
|
||||
|
||||
return the next start point in stringp
|
||||
|
||||
return the current string start;
|
||||
|
||||
*/
|
||||
|
||||
char *str_sep(char **stringp, char *delim)
|
||||
{
|
||||
int j, dl, i, sl;
|
||||
char *newstring, *ret;
|
||||
|
||||
if (*stringp == NULL)
|
||||
return NULL;
|
||||
|
||||
dl = strlen(delim);
|
||||
sl = strlen(*stringp);
|
||||
newstring = NULL;
|
||||
ret = *stringp;
|
||||
|
||||
for (i=0; i<sl; i++)
|
||||
{
|
||||
for (j=0; j<dl; j++)
|
||||
{
|
||||
if ((*stringp)[i] == delim[j])
|
||||
{
|
||||
(*stringp)[i] = '\0';
|
||||
newstring = &((*stringp)[i+1]);
|
||||
i = sl; j = dl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*stringp = newstring;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
typedef struct t_ip_cache {
|
||||
struct t_ip_cache *next;
|
||||
char *name;
|
||||
int ip;
|
||||
} t_ip_cache;
|
||||
static t_ip_cache *gIPcache = NULL;
|
||||
int check_IP_cache(char *name, int *ip)
|
||||
{
|
||||
t_ip_cache *cur = gIPcache;
|
||||
|
||||
while (cur) {
|
||||
if (str_casecmp(name, cur->name) == 0) {
|
||||
*ip = cur->ip;
|
||||
return 0;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int add_to_IP_cache(char *name, int ip)
|
||||
{
|
||||
t_ip_cache *cur;
|
||||
|
||||
cur = (t_ip_cache*)malloc(sizeof(t_ip_cache));
|
||||
if (cur == NULL)
|
||||
return -1;
|
||||
cur->ip = ip;
|
||||
cur->name = malloc(strlen(name) + 1);
|
||||
strcpy(cur->name, name);
|
||||
cur->next = gIPcache;
|
||||
gIPcache = cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**********************************************/
|
||||
int inet_aton_(char *s, int *retval)
|
||||
{
|
||||
int i, l, x, el[4], ret, good = 1;
|
||||
|
||||
x = 0, ret = 0;
|
||||
l = strlen(s);
|
||||
el[0] = 0;
|
||||
for (i=0; i<l; i++) {
|
||||
if (s[i] == '.') {
|
||||
x++;
|
||||
if (x > 3) {
|
||||
good = 0;
|
||||
break;
|
||||
}
|
||||
el[x] = 0;
|
||||
}
|
||||
else if (s[i] >= '0' && s[i] <= '9') {
|
||||
el[x] *= 10;
|
||||
el[x] += s[i] - '0';
|
||||
}
|
||||
else
|
||||
good = 0;
|
||||
}
|
||||
switch (x) {
|
||||
case 3:
|
||||
ret = ( ((el[0] << 24) & 0xff000000) |
|
||||
((el[1] << 16) & 0x00ff0000) |
|
||||
((el[2] << 8 ) & 0x0000ff00) |
|
||||
(el[3] & 0x000000ff) );
|
||||
break;
|
||||
case 2:
|
||||
ret = ( ((el[0] << 24) & 0xff000000) |
|
||||
((el[1] << 16) & 0x00ff0000) |
|
||||
(el[2] & 0x0000ffff) );
|
||||
break;
|
||||
case 1:
|
||||
ret = (((el[0] << 24) & 0xff000000) |
|
||||
(el[1] & 0x00ffffff) );
|
||||
break;
|
||||
case 0:
|
||||
ret = el[0];
|
||||
break;
|
||||
}
|
||||
*retval = ret;
|
||||
return good;
|
||||
}
|
||||
|
42
StreamingProxy.tproj/util.h
Normal file
42
StreamingProxy.tproj/util.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* util.h
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**********************************************/
|
||||
char *ip_to_string(int ip);
|
||||
int inet_aton_(char *s, int *retval);
|
||||
char *str_sep(char **stringp, char *delim);
|
||||
char *str_dup(char *str);
|
||||
int str_casecmp(char *str1, char *str2);
|
||||
int strn_casecmp(char *str1, char *str2, int l);
|
||||
|
||||
int check_IP_cache(char *name, int *ip);
|
||||
int add_to_IP_cache(char *name, int ip);
|
||||
char* get_line_str( char* strBuff, char *input, int buffSize );
|
Loading…
Add table
Add a link
Reference in a new issue