一. 背景
因为项目的需求,针对live555修改网络模块,支持IPv6的网络通信。花了将近一周多的时间,我熟悉了live555整个框架和对IPv6网络通性的学习使用,成功对live555进行修改。
二. 实现步骤
1.需求
由于live555这个开源的项目本身就只支持IPv4网络地址通信,并没有拓展对IPv6的网络通信支持,所以经过验证之后,确定将必须将live555项目的IPv4的所有有关接口都修改为IPv6,IPv6的通信不仅支持IPv6的地址访问,也支持对IPv4的地址访问。
2.编码。
经过确认后,开始着手修改。修改的线索是socket的建立通信机制socket->bind->listen->accept-> recv/send这样出发,结合live555对RTSP的server的实现进行对应的修改。具体修改 是:main()->rtspserver->createNew()->setUpOurSocket()->setupStreamSocket()->createSocket()这条修改路线中,将所有IPv4的网络参数和设置都修改为IPv6的通信的支持。由setUpOurSocket()返回创建绑定监听的socket之后,传给new RTSPServer(env, ourSocket, ourPort, authDatabase, reclamationTestSeconds)->incomingConnectionHandlerRTSP()->incomingConnectionHandlerRTSP1()->incomingConnectionHandler(fRTSPServerSocket)->accept();再由accept这个函数返回已经连接到server的clientaddr,并将这个传入(void)createNewClientConnection(clientSocket, clientAddr),实现为每个client创建对应的会话。同样对这个线路中涉及到的IPv4的网络参数都将修改为IPv6的网络参数。因为代码修改的部分较多,所以具体详细的修改见下面的具体代码修改记录。
3.实现。
在对live这个项目的源码,修改完毕后。在live 当前路径下执行:
#make clean
#make
执行编译,生成rtspserver。没有出错,修改成功
4. 测试
整个live555项目的文件,如下图2-1所示
图2-1 live555项目
测试步骤,首先要mediaServer目录下放一个h264的文件,因为在运行live555MediaServer的时候,会在当前的目录下寻找播放的资源,如果你没有h264文件话,可以在www.live555.com的官网中可以在到一些测试可用的文件;接下来的步骤就是执行修改完后的live555MediaServer文件了,如下图2-2,图2-3所示
图2-2 live555MediaServer目录
图2-3 运行live555MediaServer
注:因为现在VLC播放还是不支持IPv6地址播放的,所以不可以使用VLC测试视频。
三. 具体代码修改记录
#####################UsageEnvironment.hh################################
在UsageEnvironment.hh中,添加:
...
// David made a few change for IPv6
#ifndef DAVID
#define DAVID
#end
...
####################NetAddress.hh#################################
在NetAddress.hh中
...
typedef u_int32_t netAddressBits;
修改如下
//David made a few change for IPv6
#ifndef DAVID
typedef u_int32_t netAddressBits;
#else
typedef struct in6_addr netAddressBits;
#endif
...
/*****/
//class AddressString{} //修改如下
class AddressString {
public:
AddressString(struct sockaddr_in const& addr);
AddressString(struct in_addr const& addr);
AddressString(u_int32_t addr); // David netAddressBits->u_int32_t
//David add
AddressString(struct sockaddr_in6 const& addr);
AddressString(struct in6_addr const& addr);
AddressString(netAddressBits& addr); // "addr" is assumed to be in host byte order here
virtual ~AddressString();
char const* val() const { return fVal; }
private:
//David add
//void init(netAddressBits->u_int32_t)
void init_4(u_int32_t addr);
void init_6(netAddressBits addr);
private:
char* fVal; // The result ASCII string: allocated by the constructor; deleted by the destructor
};
####################NetAddress.cpp#################################
在NetAddress.cpp中
...
void* AddressPortLookupTable::Add(netAddressBits address1,
netAddressBits address2,
Port port, void* value) {
/* David
int key[3];
key[0] = (int)address1;
key[1] = (int)address2;
key[2] = (int)port.num();
return fTable->Add((char*)key, value);
*/
int key[9];
memcpy(&key[0], &address1.s6_addr[0], 4);
memcpy(&key[1], &address1.s6_addr[4], 4);
memcpy(&key[2], &address1.s6_addr[8], 4);
memcpy(&key[3], &address1.s6_addr[12], 4);
memcpy(&key[4], &address2.s6_addr[0], 4);
memcpy(&key[5], &address2.s6_addr[4], 4);
memcpy(&key[6], &address2.s6_addr[8], 4);
memcpy(&key[7], &address2.s6_addr[12], 4);
key[8] = (int)port.num();
return fTable->Add((char*)key, value);
}
void* AddressPortLookupTable::Lookup(netAddressBits address1,
netAddressBits address2,
Port port) {
/* David
int key[3];
key[0] = (int)address1;
key[1] = (int)address2;
key[2] = (int)port.num();
return fTable->Lookup((char*)key);
*/
int key[9];
memcpy(&key[0], &address1.s6_addr[0], 4);
memcpy(&key[1], &address1.s6_addr[4], 4);
memcpy(&key[2], &address1.s6_addr[8], 4);
memcpy(&key[3], &address1.s6_addr[12], 4);
memcpy(&key[4], &address2.s6_addr[0], 4);
memcpy(&key[5], &address2.s6_addr[4], 4);
memcpy(&key[6], &address2.s6_addr[8], 4);
memcpy(&key[7], &address2.s6_addr[12], 4);
key[8] = (int)port.num();
return fTable->Lookup((char*)key);
}
Boolean AddressPortLookupTable::Remove(netAddressBits address1,
netAddressBits address2,
Port port) {
/* David
int key[3];
key[0] = (int)address1;
key[1] = (int)address2;
key[2] = (int)port.num();
return fTable->Remove((char*)key);
*/
int key[9];
memcpy(&key[0], &address1.s6_addr[0], 4);
memcpy(&key[1], &address1.s6_addr[4], 4);
memcpy(&key[2], &address1.s6_addr[8], 4);
memcpy(&key[3], &address1.s6_addr[12], 4);
memcpy(&key[4], &address2.s6_addr[0], 4);
memcpy(&key[5], &address2.s6_addr[4], 4);
memcpy(&key[6], &address2.s6_addr[8], 4);
memcpy(&key[7], &address2.s6_addr[12], 4);
key[8] = (int)port.num();
return fTable->Remove((char*)key);
}
AddressPortLookupTable::Iterator::Iterator(AddressPortLookupTable& table)
: fIter(HashTable::Iterator::create(*(table.fTable))) {
}
AddressPortLookupTable::Iterator::~Iterator() {
delete fIter;
}
void* AddressPortLookupTable::Iterator::next() {
char const* key; // dummy
return fIter->next(key);
}
// isMulticastAddress() implementation //
Boolean IsMulticastAddress(netAddressBits address) {
// Note: We return False for addresses in the range 224.0.0.0
// through 224.0.0.255, because these are non-routable
// Note: IPv4-specific #####
//IPv6: ff00::/8
#ifndef DAVID
netAddressBits addressInNetworkOrder = htonl(address);
return addressInNetworkOrder > 0xE00000FF &&
addressInNetworkOrder <= 0xEFFFFFFF;
#else
netAddressBits addressInNetworkOrder = address;
return addressInNetworkOrder.s6_addr[0] == 0xFF ;
#endif
}
// AddressString implementation //
#if 0
AddressString::AddressString(struct sockaddr_in const& addr) {
init(addr.sin_addr.s_addr);
}
AddressString::AddressString(struct in_addr const& addr) {
init(addr.s_addr);
}
AddressString::AddressString(netAddressBits addr) {
init(addr);
}
void AddressString::init(netAddressBits addr) {
fVal = new char[16]; // large enough for "abc.def.ghi.jkl"
netAddressBits addrNBO = htonl(addr); // make sure we have a value in a known byte order: big endian
sprintf(fVal, "%u.%u.%u.%u", (addrNBO>>24)&0xFF, (addrNBO>>16)&0xFF, (addrNBO>>8)&0xFF, addrNBO&0xFF);
}
#endif //修改如下
AddressString::AddressString(struct sockaddr_in const& addr) {
init_4(addr.sin_addr.s_addr);
}
AddressString::AddressString(struct in_addr const& addr) {
init_4(addr.s_addr);
}
AddressString::AddressString(u_int32_t addr) {
init_4(addr);
}
void AddressString::init_4(u_int32_t addr) {
fVal = new char[16]; // large enough for "abc.def.ghi.jkl"
u_int32_t addrNBO = htonl(addr); // make sure we have a value in a known byte order: big endian
sprintf(fVal, "%u.%u.%u.%u", (addrNBO>>24)&0xFF, (addrNBO>>16)&0xFF, (addrNBO>>8)&0xFF, addrNBO&0xFF);
}
AddressString::AddressString(struct sockaddr_in6 const& addr) {
init_6(addr.sin6_addr);
}
AddressString::AddressString(struct in6_addr const& addr) {
init_6(addr);
}
AddressString::AddressString(netAddressBits& addr) {
init_6(addr);
}
void AddressString::init_6(netAddressBits addr) {
int len = sizeof(struct in6_addr);
fVal = new char[len];
inet_ntop(AF_INET6, &addr, fVal, len);
}
####################RTSPServer.hh#################################
在RTSPServer.hh中:
...
class RTSPServer: public Medium {
protected:
...
virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in6& clientAddr,
char const* urlSuffix);
virtual Boolean specialClientUserAccessCheck(int clientSocket, struct sockaddr_in6& clientAddr,
char const* urlSuffix, char const *username);
...
}
...
class RTSPClientConnection {
...
public:
RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in6 clientAddr);
...
protected:
struct sockaddr_in6 fClientAddr;
...
}
####################RTSPServer.cpp#################################
在RTSPServer.cpp中:
/*****/
Boolean RTSPServer
::specialClientAccessCheck(int /*clientSocket*/, struct sockaddr_in6& /*clientAddr*/, char const* /*urlSuffix*/) {
// default implementation
return True;
}
Boolean RTSPServer
::specialClientUserAccessCheck(int /*clientSocket*/, struct sockaddr_in6& /*clientAddr*/,
char const* /*urlSuffix*/, char const * /*username*/) {
// default implementation; no further access restrictions:
return True;
}
/*****/
RTSPServer::RTSPClientConnection::~RTSPClientConnection() {
...
if(fOurServer.m_callbackEvent)
fOurServer.m_callbackEvent(1, (void*)AddressString(fClientAddr.sin6_addr).val()); //David sin_addr->sin6_addr
...
}
/*****/
#if 0 //David do
int RTSPServer::registerStream(ServerMediaSession* serverMediaSession,
char const* remoteClientNameOrAddress, Port remotePort,
responseHandlerForREGISTER* responseHandler)
#endif
/*****/
char* RTSPServer::rtspURLPrefix(int clientSocket, int isPSIA) const {
struct sockaddr_in6 ourAddress;
...
//David
/*ourAddress.sin_addr.s_addr = ReceivingInterfaceAddr != 0
? ReceivingInterfaceAddr
: ourIPAddress(envir()); // hack*/ //修改如下
ourAddress.sin6_addr = ourIPAddress(envir());
}
/*****/
int RTSPServer::setUpOurSocket(UsageEnvironment& env, Port& ourPort) {
...
//ourSocket = setupStreamSocket(env, ourPort); 修改如下
ourSocket = setupStreamSocket(env, ourPort, True, 1);
...
}
/*****/
void RTSPServer::RTSPClientConnection::incomingRequestHandler1() {
struct sockaddr_in6 dummy; // 'from' address, meaningless in this case
...
}
/*****/
void RTSPServer::incomingConnectionHandler(int serverSocket) {
struct sockaddr_in6 clientAddr;
...
}
/*****/
void RTSPServer::RTSPClientSession
::handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection,
char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr){
...
netAddressBits destinationAddress = in6addr_any;
...
struct sockaddr_in6 sourceAddr;
...
#ifdef HACK_FOR_MULTIHOMED_SERVERS
//ReceivingInterfaceAddr = SendingInterfaceAddr = sourceAddr.sin_addr.s_addr; 修改如下
ReceivingInterfaceAddr = SendingInterfaceAddr = sourceAddr.sin6_addr;
#endif
//David fClientAddr.sin_addr.s_addr -> fClientAddr.sin6_addr
subsession->getStreamParameters(fOurSessionId, ourClientConnection->fClientAddr.sin6_addr,
clientRTPPort, clientRTCPPort,
tcpSocketNum, rtpChannelId, rtcpChannelId,
destinationAddress, destinationTTL, fIsMulticast,
serverRTPPort, serverRTCPPort,
fStreamStates[streamNum].streamToken);
...
}
/*****/
RTSPServer::RTSPClientConnection*
RTSPServer::createNewClientConnection(int clientSocket, struct sockaddr_in6 clientAddr) {
return new RTSPClientConnection(*this, clientSocket, clientAddr);
}
/*****/
RTSPServerWithREGISTERProxying::RTSPClientConnection*
RTSPServerWithREGISTERProxying::createNewClientConnection(int clientSocket, struct sockaddr_in6 clientAddr) {
return new RTSPClientConnectionWithREGISTERProxying(*this, clientSocket, clientAddr);
}
/*****/
RTSPServerWithREGISTERProxying::RTSPClientConnectionWithREGISTERProxying
::RTSPClientConnectionWithREGISTERProxying(RTSPServer& ourServer, int clientSocket, struct sockaddr_in6 clientAddr)
: RTSPServer::RTSPClientConnection(ourServer, clientSocket, clientAddr) {
}
/*****/
void RTSPServer::RegisterRequestRecord::incomingResponseHandler1() {
struct sockaddr_in6 fromAddr;
...
}
########################GroupsocketHelper.hh#############################
在GroupsocketHelper.hh中:
...
//David add int nfamily = 1
int setupDatagramSocket(UsageEnvironment& env, Port port, int nfamily = 0);
/*****/
int setupStreamSocket(UsageEnvironment& env,
Port port, Boolean makeNonBlocking = True, int nfamily = 0);
/*****/
int readSocket(UsageEnvironment& env,
int socket, unsigned char* buffer, unsigned bufferSize,
struct sockaddr_in6& fromAddress);
/*****/
Boolean writeSocket(UsageEnvironment& env,
int socket, struct in6_addr address, Port port,
u_int8_t ttlArg,
unsigned char* buffer, unsigned bufferSize);
/*****/
...
#ifndef DAVID
#define MAKE_SOCKADDR_IN(var,adr,prt) /*adr,prt must be in network order*/\
struct sockaddr_in var;\
var.sin_family = AF_INET;\
var.sin_addr.s_addr = (adr);\
var.sin_port = (prt);\
SET_SOCKADDR_SIN_LEN(var);
#else //David add
#define MAKE_SOCKADDR_IN(var,adr,prt) /*adr,prt must be in network order*/\
struct sockaddr_in6 var;\
var.sin6_family = AF_INET6;\
var.sin6_addr = (adr);\
var.sin6_port = (prt);\
SET_SOCKADDR_SIN_LEN(var);
#endif
/*****/
########################GroupsocketHelper.cpp#############################
在GroupsocketHelper.cpp中:
/*****/
//netAddressBits SendingInterfaceAddr = INADDR_ANY;
//netAddressBits ReceivingInterfaceAddr = INADDR_ANY;
修改如下
#ifndef DAVID
netAddressBits SendingInterfaceAddr = INADDR_ANY;
netAddressBits ReceivingInterfaceAddr = INADDR_ANY;
#else
netAddressBits SendingInterfaceAddr = in6addr_any;
netAddressBits ReceivingInterfaceAddr = in6addr_any;
netAddressBits in6addr0 = in6addr_any;
#endif
/*****/
static int createSocket(int type)改为static int createSocket(int type, int nfamily)
/*****/
static int createSocket(int type, int nfamily){
...
//sock = socket(AF_INET, type|SOCK_CLOEXEC, 0); 修改如下
if (nfamily == 0)
sock = socket(AF_INET, type|SOCK_CLOEXEC, 0);
else
sock = socket(AF_INET6, type|SOCK_CLOEXEC, 0);
...
//sock = socket(AF_INET, type, 0); 修改如下
if (nfamily == 0)
sock = socket(AF_INET, type, 0);
else
sock = socket(AF_INET6, type, 0);
...
}
/*****/
int setupStreamSocket(UsageEnvironment& env,
Port port, Boolean makeNonBlocking)
改为:
int setupStreamSocket(UsageEnvironment& env,
Port port, Boolean makeNonBlocking, int nfamily)
/*****/
int setupDatagramSocket(UsageEnvironment& env, Port port, int nfamily) {
//David add int nfamily;
...
#if 0
#ifdef IP_MULTICAST_LOOP
const u_int8_t loop = 1;
if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
(const char*)&loop, sizeof loop) < 0) {
socketErr(env, "setsockopt(IP_MULTICAST_LOOP) error: ");
closeSocket(newSocket);
return -1;
}
#endif
#endif
...
//netAddressBits addr = INADDR_ANY;
netAddressBits addr = in6addr_any;
...
//if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
if (port.num() != 0 || memcmp(&ReceivingInterfaceAddr, &in6addr0, sizeof(struct in6_addr))!=0) {
...
if (nfamily == 0){
MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
char tmpBuffer[100];
sprintf(tmpBuffer, "bind() error (port number: %d): ",
ntohs(port.num()));
socketErr(env, tmpBuffer);
closeSocket(newSocket);
return -1;
}
}else{ /*David*/
//env << "David, bind IPv6 now...\n";
struct sockaddr_in6 name; // IPv6
bzero(&name, sizeof(name));
name.sin6_family =AF_INET6;
name.sin6_port = port.num();
name.sin6_addr = in6addr_any;
if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
char tmpBuffer[100];
sprintf(tmpBuffer, "bind() error (port number: %d): ",
ntohs(port.num()));
socketErr(env, tmpBuffer);
closeSocket(newSocket);
return -1;
}
//env << "David, bind ok\n";
}
...
//if (SendingInterfaceAddr != INADDR_ANY) {
//struct in_addr addr;
//addr.s_addr = SendingInterfaceAddr;
//if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_IF,
if (memcmp(&SendingInterfaceAddr, &in6addr0, sizeof(in6addr0))!=0){
struct in6_addr addr;
addr = SendingInterfaceAddr
if (setsockopt(newSocket, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(const char*)&addr, sizeof addr) < 0) {
...
}
}
}
/*****/
int setupStreamSocket(UsageEnvironment& env,
Port port, Boolean makeNonBlocking, int nfamily){
...
//int newSocket = createSocket(SOCK_STREAM); 修改如下
int newSocket = createSocket(SOCK_STREAM, nfamily);
...
//if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
修改如下
#ifndef DAVID
if (port.num() != 0 || ReceivingInterfaceAddr != INADDR_ANY) {
#else
if (port.num() != 0 || memcmp(&ReceivingInterfaceAddr, &in6addr0, sizeof(struct in6_addr)) != 0) {
#endif
...
/*MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
char tmpBuffer[100];
sprintf(tmpBuffer, "bind() error (port number: %d): ",
ntohs(port.num()));
socketErr(env, tmpBuffer);
closeSocket(newSocket);
return -1;
}*/ 修改如下
if (nfamily == 0){
MAKE_SOCKADDR_IN(name, ReceivingInterfaceAddr, port.num());
if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
char tmpBuffer[100];
sprintf(tmpBuffer, "bind() error (port number: %d): ",
ntohs(port.num()));
socketErr(env, tmpBuffer);
closeSocket(newSocket);
return -1;
}
}else{ /*David*/
//env << "David, bind IPv6 now...\n";
struct sockaddr_in6 name; // IPv6
bzero(&name, sizeof(name));
name.sin6_family = AF_INET6;
name.sin6_port = port.num();
name.sin6_addr = in6addr_any;
if (bind(newSocket, (struct sockaddr*)&name, sizeof name) != 0) {
char tmpBuffer[100];
sprintf(tmpBuffer, "bind() error (port number: %d): ",
ntohs(port.num()));
socketErr(env, tmpBuffer);
closeSocket(newSocket);
return -1;
}
}
...
}
/*****/
//David struct sockaddr_in->struct sockaddr_in6
int readSocket(UsageEnvironment& env,
int socket, unsigned char* buffer, unsigned bufferSize,
struct sockaddr_in6& fromAddress)
/*****/
Boolean writeSocket(UsageEnvironment& env,
int socket, struct in6_addr address, Port port,
u_int8_t ttlArg,
unsigned char* buffer, unsigned bufferSize) {
...
//MAKE_SOCKADDR_IN(dest, address.s_addr, port.num());
MAKE_SOCKADDR_IN(dest, address, port.num());
...
}
/*****/
Boolean socketJoinGroup(UsageEnvironment& env, int socket,
netAddressBits groupAddress){
...
//David
//struct ip_mreq imr;
//imr.imr_multiaddr.s_addr = groupAddress;
//imr.imr_interface.s_addr = ReceivingInterfaceAddr;
//if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
// (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
struct ipv6_mreq imr;
memcpy(&imr.ipv6mr_multiaddr, &groupAddress, sizeof(struct in6_addr));
imr.ipv6mr_interface = 0;
if (setsockopt(socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(const char*)&imr, sizeof (struct ipv6_mreq)) < 0) {
...
}
...
}
/*****/
Boolean socketLeaveGroup(UsageEnvironment&, int socket,
netAddressBits groupAddress) {
...
//David
//struct ip_mreq imr;
//imr.imr_multiaddr.s_addr = groupAddress;
//imr.imr_interface.s_addr = ReceivingInterfaceAddr;
//if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
// (const char*)&imr, sizeof (struct ip_mreq)) < 0) {
struct ipv6_mreq imr;
memcpy(&imr.ipv6mr_multiaddr, &groupAddress, sizeof(struct in6_addr));
imr.ipv6mr_interface = 0;
if (setsockopt(socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
(const char*)&imr, sizeof (struct ipv6_mreq)) < 0) {
...
}
...
}
/*****/
#if 0
#if !defined(IP_ADD_SOURCE_MEMBERSHIP)
struct ip_mreq_source {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_sourceaddr; /* IP address of source */
struct in_addr imr_interface; /* local IP address of interface */
};
#endif
#ifndef IP_ADD_SOURCE_MEMBERSHIP
#ifdef LINUX
#define IP_ADD_SOURCE_MEMBERSHIP 39
#define IP_DROP_SOURCE_MEMBERSHIP 40
#else
#define IP_ADD_SOURCE_MEMBERSHIP 25
#define IP_DROP_SOURCE_MEMBERSHIP 26
#endif
#endif
#endif
#ifndef IPV6_ADD_SOURCE_MEMBERSHIP
#ifdef LINUX
#define IPV6_ADD_SOURCE_MEMBERSHIP 39
#define IPV6_DROP_SOURCE_MEMBERSHIP 40
#else
#define IPV6_ADD_SOURCE_MEMBERSHIP 25
#define IPV6_DROP_SOURCE_MEMBERSHIP 26
#endif
#endif
/*****/
Boolean socketJoinGroupSSM(UsageEnvironment& env, int socket,
netAddressBits groupAddress,
netAddressBits sourceFilterAddr) {
if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
//struct ip_mreq_source imr;
struct group_source_req imr;
#ifdef ANDROID
//imr.imr_multiaddr = groupAddress;
//imr.imr_sourceaddr = sourceFilterAddr;
//imr.imr_interface = ReceivingInterfaceAddr;
imr.gsr_group = (struct sockaddr_in6)groupAddress;
imr.gsr_source = (struct sockaddr_in6)sourceFilterAddr;
imr.gsr_interface = (struct sockaddr_in6)ReceivingInterfaceAddr;
#else
//imr.imr_multiaddr.s_addr = groupAddress;
//imr.imr_sourceaddr.s_addr = sourceFilterAddr;
//imr.imr_interface.s_addr = ReceivingInterfaceAddr;
memcpy(&imr.gsr_group, &groupAddress, sizeof(struct sockaddr_in6));
memcpy(&imr.gsr_source, &sourceFilterAddr, sizeof(struct sockaddr_in6));
memcpy(&imr.gsr_interface, &ReceivingInterfaceAddr, sizeof(struct sockaddr_in6));
#endif
//if (setsockopt(socket, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP,
// (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
if (setsockopt(socket, IPPROTO_IPV6, IPV6_ADD_SOURCE_MEMBERSHIP,
(const char*)&imr, sizeof (struct group_source_req)) < 0) {
socketErr(env, "setsockopt(IPV6_ADD_SOURCE_MEMBERSHIP) error: ");
return False;
}
return True;
}
/*****/
Boolean socketLeaveGroupSSM(UsageEnvironment& /*env*/, int socket,
netAddressBits groupAddress,
netAddressBits sourceFilterAddr) {
if (!IsMulticastAddress(groupAddress)) return True; // ignore this case
//struct ip_mreq_source imr;
struct group_source_req imr;
#ifdef ANDROID
imr.imr_multiaddr = groupAddress;
imr.imr_sourceaddr = sourceFilterAddr;
imr.imr_interface = ReceivingInterfaceAddr;
#else
//imr.imr_multiaddr.s_addr = groupAddress;
//imr.imr_sourceaddr.s_addr = sourceFilterAddr;
//imr.imr_interface.s_addr = ReceivingInterfaceAddr;
memcpy(&imr.gsr_group, &groupAddress, sizeof(struct sockaddr_in6));
memcpy(&imr.gsr_source, &sourceFilterAddr, sizeof(struct sockaddr_in6));
memcpy(&imr.gsr_interface, &ReceivingInterfaceAddr, sizeof(struct sockaddr_in6));
#endif
//if (setsockopt(socket, IPPROTO_IP, IP_DROP_SOURCE_MEMBERSHIP,
// (const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
if (setsockopt(socket, IPPROTO_IPV6, IPV6_DROP_SOURCE_MEMBERSHIP,
(const char*)&imr, sizeof (struct ip_mreq_source)) < 0) {
return False;
}
return True;
}
/*****/
static Boolean getSourcePort0(int socket, portNumBits& resultPortNum/*host order*/) {
sockaddr_in6 test; test.sin6_port = 0;
...
resultPortNum = ntohs(test.sin6_port);
...
}
/*****/
static Boolean getSourcePort0(int socket, portNumBits& resultPortNum/*host order*/) {
...
//MAKE_SOCKADDR_IN(name, INADDR_ANY, 0);
MAKE_SOCKADDR_IN(name, in6addr_any, 0);
...
}
/*****/
static Boolean badAddressForUs(netAddressBits addr) {
// Check for some possible erroneous addresses:
//David
//netAddressBits nAddr = htonl(addr);
//return (nAddr == 0x7F000001 /* 127.0.0.1 */
// || nAddr == 0
// || nAddr == (netAddressBits)(~0));
char ntopaddr[128];
inet_ntop(AF_INET6, &addr, ntopaddr, sizeof(struct in6_addr));
return (memcmp(ntopaddr, "::1", sizeof(struct in6_addr))==0
|| memcmp(ntopaddr, "0:0:0:0:0:0:0:0", sizeof(struct in6_addr))==0
|| memcmp(ntopaddr, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", sizeof(struct in6_addr))==0
);
}
/*****/
//David made a few change for IPv6
netAddressBits ourIPAddress(UsageEnvironment& env) {
//static netAddressBits ourAddress = 0;
static netAddressBits ourAddress = in6addr_any;
...
//struct in_addr testAddr;
struct in6_addr testAddr;
...
//if (ourAddress == 0) {
if (memcmp(&ourAddress, &in6addr0, sizeof(in6addr0)) == 0) {
// We need to find our source address
//struct sockaddr_in fromAddr;
//fromAddr.sin_addr.s_addr = 0;
struct sockaddr_in6 fromAddr;
fromAddr.sin6_addr = in6addr0;
.
}
do{
...
//testAddr.s_addr = our_inet_addr("228.67.43.91"); // arbitrary
inet_pton(AF_INET6,"ff0e::2",&testAddr);
...
sock = setupDatagramSocket(env, testPort, 1);
...
loopbackWorks = !badAddressForUs(fromAddr.sin6_addr);
...
}while(0);
...
//unsigned seed = ourAddress^timeNow.tv_sec^timeNow.tv_usec;
unsigned seed = timeNow.tv_sec^timeNow.tv_usec;
...
}
/*****/
########################RTCP.cpp#############################
在RTCP.cpp中:
/*****/
void RTCPInstance
::setSpecificRRHandler(netAddressBits fromAddress, Port fromPort,
TaskFunc* handlerTask, void* clientData){
...
//David
//fSpecificRRHandlerTable->Add(fromAddress, (~0), fromPort, rrHandler); 修改如下
const char *buff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
netAddressBits in6addr1;
inet_pton(AF_INET6, buff, &in6addr1);
fSpecificRRHandlerTable->Add(fromAddress, in6addr1, fromPort, rrHandler);
}
/*****/
void RTCPInstance
::unsetSpecificRRHandler(netAddressBits fromAddress, Port fromPort){
if (fSpecificRRHandlerTable == NULL) return;
//David
const char *buff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
netAddressBits in6addr1;
inet_pton(AF_INET6, buff, &in6addr1);
RRHandlerRecord* rrHandler
= (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddress, in6addr1, fromPort)); //第二参数(~0)->in6addr1
if (rrHandler != NULL) {
fSpecificRRHandlerTable->Remove(fromAddress, in6addr1, fromPort); //第二参数(~0)->in6addr1
delete rrHandler;
}
}
}
/*****/
void RTCPInstance::incomingReportHandler1(){
...
//struct sockaddr_in fromAddress; 修改如下
struct sockaddr_in6 fromAddress;
...
//fromAddr = fromAddress.sin_addr.s_addr;
//fromPortNum = ntohs(fromAddress.sin_port); 修改如下
fromAddr = fromAddress.sin6_addr;
fromPortNum = ntohs(fromAddress.sin6_port);
...
//David
//fromAddr = tcpReadStreamSocketNum; 修改如下
memset(&fromAddr, 0,sizeof(fromAddr));
memcpy(&fromAddr,&tcpReadStreamSocketNum,4);
...
//David add
const char *buff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
netAddressBits in6addr1;
inet_pton(AF_INET6, buff, &in6addr1);
RRHandlerRecord* rrHandler
= (RRHandlerRecord*)(fSpecificRRHandlerTable->Lookup(fromAddr, in6addr1, fromPort)); //第二参数(~0)->in6addr1
}
########################RTPinterface.hh#############################
在RTPInterface.hh中:
Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead, struct sockaddr_in6& fromAddress, Boolean& packetReadWasIncomplete);
//将struct sockaddr_in->struct sockaddr_in6
########################RTPinterface.cpp#############################
在RTPinterface.cpp中:
Boolean RTPInterface::handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead, struct sockaddr_in6& fromAddress, Boolean& packetReadWasIncomplete)
//将struct sockaddr_in->struct sockaddr_in6
/*****/
Boolean SocketDescriptor::tcpReadHandler1(int mask) {
...
struct sockaddr_in6 fromAddress;
...
}
########################Groupsock.hh#############################
在Groupsock.hh中:
class OutputSocket: public Socket {
private:
virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead,
struct sockaddr_in6& fromAddress);
}
/*****/
class destRecord {
public:
destRecord(struct in6_addr const& addr, Port const& port, u_int8_t ttl,
destRecord* next);
};
/*****/
class Groupsock: public OutputSocket {
public:
Groupsock(UsageEnvironment& env, struct in6_addr const& groupAddr,
Port port, u_int8_t ttl);
// used for a 'source-independent multicast' group
Groupsock(UsageEnvironment& env, struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
Port port);
// used for a 'source-specific multicast' group
virtual ~Groupsock();
void changeDestinationParameters(struct in6_addr const& newDestAddr,
Port newDestPort, int newDestTTL);
void addDestination(struct in6_addr const& addr, Port const& port);
void removeDestination(struct in6_addr const& addr, Port const& port);
void removeAllDestinations();
struct in6_addr const& groupAddress() const {
return fIncomingGroupEId.groupAddress();
}
struct in6_addr const& sourceFilterAddress() const {
return fIncomingGroupEId.sourceFilterAddress();
}
Boolean wasLoopedBackFromUs(UsageEnvironment& env,
struct sockaddr_in6& fromAddress);
public: // redefined virtual functions
virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead,
struct sockaddr_in6& fromAddress);
}
########################Groupsock.cpp#############################
在Groupsock.cpp中:
...
Boolean OutputSocket::write(netAddressBits address, Port port, u_int8_t ttl,
unsigned char* buffer, unsigned bufferSize) {
...
//David
struct in6_addr destAddr; destAddr = address;
...
}
/*****/
Boolean OutputSocket
::handleRead(unsigned char* /*buffer*/, unsigned /*bufferMaxSize*/,
unsigned& /*bytesRead*/, struct sockaddr_in6& /*fromAddress*/) {
return True;
}
/*****/
destRecord
::destRecord(struct in6_addr const& addr, Port const& port, u_int8_t ttl,
destRecord* next)
: fNext(next), fGroupEId(addr, port.num(), ttl), fPort(port) {
}
/*****/
Groupsock::Groupsock(UsageEnvironment& env, struct in6_addr const& groupAddr,
Port port, u_int8_t ttl):...{
//David groupAddr.s_addr -> groupAddr
if (!socketJoinGroup(env, socketNum(), groupAddr)) {
...
}
...
//if (ourIPAddress(env) == 0) {
netAddressBits in6addr = in6addr_any;
netAddressBits ipaddr = ourIPAddress(env);
if(memcmp(&ipaddr, &in6addr, sizeof(struct in6_addr)) == 0){
...
}
...
}
/*****/
Groupsock::Groupsock(UsageEnvironment& env, struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
Port port):...{
...
if (!socketJoinGroupSSM(env, socketNum(), groupAddr,
sourceFilterAddr)) {
...
}
...
if (!socketJoinGroup(env, socketNum(), groupAddr)) {
if (DebugLevel >= 1) {
}
...
}
/*****/
void
Groupsock::changeDestinationParameters(struct in6_addr const& newDestAddr,
Port newDestPort, int newDestTTL) {
...
struct in_addr destAddr = fDests->fGroupEId.groupAddress();
netAddressBits in6addr0 = in6addr_any;
//if (newDestAddr.s_addr != 0) {
//if (newDestAddr.s_addr != destAddr.s_addr
if (memcmp(&newDestAddr, &in6addr0, sizeof(in6addr0)) != 0) {
if(memcmp(&newDestAddr, &destAddr, sizeof(struct in6_addr)) !=0
&& IsMulticastAddress(newDestAddr.s_addr)) {
// If the new destination is a multicast address, then we assume that
// we want to join it also. (If this is not in fact the case, then
// call "multicastSendOnly()" afterwards.)
//David groupAddr.s_addr -> groupAddr
socketLeaveGroup(env(), socketNum(), destAddr);
socketJoinGroup(env(), socketNum(), newDestAddr);
}
destAddr = newDestAddr;
}
....
}
/*****/
Boolean Groupsock::handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead,
struct sockaddr_in6& fromAddress) {
//David struct sockaddr_in -> struct sockaddr_in6
...
//if (isSSM()&& fromAddress.sin_addr.s_addr != sourceFilterAddress().s_addr) { //修改如下
if (isSSM()&& fromAddress.sin6_addr.s6_addr != sourceFilterAddress().s6_addr) {
...
/*David
numMembers =
outputToAllMembersExcept(NULL, ttl(),
buffer, bytesRead,
fromAddress.sin_addr.s_addr);*/ //修改如下
numMembers =
outputToAllMembersExcept(NULL, ttl(),
buffer, bytesRead,
fromAddress.sin6_addr);
...
}
/*****/
Boolean Groupsock::wasLoopedBackFromUs(UsageEnvironment& env,
struct sockaddr_in6& fromAddress) { //将struct sockaddr_in->struct sockaddr_in6
//David
//struct sockaddr_in->struct sockaddr_in6
//if (fromAddress.sin_addr.s_addr == ourIPAddress(env)) {
//if (fromAddress.sin_port == sourcePortNum()) { //修改如下
netAddressBits ipaddr = ourIPAddress(env);
if(memcmp(&fromAddress.sin6_addr, &ipaddr, sizeof(struct in6_addr)) == 0){
if (fromAddress.sin6_port == sourcePortNum()) {
}
/*****/
Groupsock*
GroupsockLookupTable::Fetch(UsageEnvironment& env,
netAddressBits groupAddress,
Port port, u_int8_t ttl,
Boolean& isNew) {
...
#ifdef DAVID
const char *addrbuff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
struct in6_addr in6addr1;
inet_pton(AF_INET6, addrbuff, &in6addr1);
#endif
groupsock = (Groupsock*) fTable.Lookup(groupAddress, in6addr1, port);
...
}
/*****/
Groupsock*
GroupsockLookupTable::Lookup(netAddressBits groupAddress, Port port) {
#ifdef DAVID
const char *addrbuff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
struct in6_addr in6addr1;
inet_pton(AF_INET6, addrbuff, &in6addr1);
#endif
return (Groupsock*) fTable.Lookup(groupAddress, in6addr1, port);
}
/*****/
Groupsock* GroupsockLookupTable::AddNew(UsageEnvironment& env,
netAddressBits groupAddress,
netAddressBits sourceFilterAddress,
Port port, u_int8_t ttl) {
...
struct in6_addr groupAddr; groupAddr = groupAddress;
#ifdef DAVID
const char *addrbuff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
struct in6_addr in6addr1;
inet_pton(AF_INET6, addrbuff, &in6addr1);
#endif
//if (sourceFilterAddress == netAddressBits(~0)) {
if (memcmp(&sourceFilterAddress, &in6addr1, sizeof(in6addr1)) == 0) {
...
}
########################RTPSink.hh#############################
在RTPSink.hh中:
/*****/
class RTPTransmissionStatsDB{
...
//David struct sockaddr_in->struct sockaddr_in6
void noteIncomingRR(u_int32_t SSRC, struct sockaddr_in6 const& lastFromAddress,
unsigned lossStats, unsigned lastPacketNumReceived,
unsigned jitter, unsigned lastSRTime, unsigned diffSR_RRTime);
...
}
/*****/
class RTPTransmissionStats {
...
struct sockaddr_in6 const& lastFromAddress() const {return fLastFromAddress;}
...
//David struct sockaddr_in->struct sockaddr_in6
void noteIncomingRR(struct sockaddr_in6 const& lastFromAddress,
unsigned lossStats, unsigned lastPacketNumReceived,
unsigned jitter,
unsigned lastSRTime, unsigned diffSR_RRTime);
...
pritave:
...
struct sockaddr_in6 fLastFromAddress;
}
########################RTPSink.cpp#############################
在RTPSink.cpp中:
/*****/
void RTPTransmissionStatsDB
::noteIncomingRR(u_int32_t SSRC, struct sockaddr_in6 const& lastFromAddress,
unsigned lossStats, unsigned lastPacketNumReceived,
unsigned jitter, unsigned lastSRTime, unsigned diffSR_RRTime)
//将struct sockaddr_in->struct sockaddr_in6
/*****/
//David struct sockadddr_in->struct sockaddr_in6
void RTPTransmissionStats
::noteIncomingRR(struct sockaddr_in6 const& lastFromAddress,
unsigned lossStats, unsigned lastPacketNumReceived,
unsigned jitter, unsigned lastSRTime,
unsigned diffSR_RRTime)
//将struct sockaddr_in->struct sockaddr_in6
########################MultiFramedRTPSource.cpp#############################
在MultiFramedRTPSource.cpp中:
Boolean BufferedPacket::fillInData(RTPInterface& rtpInterface, Boolean& packetReadWasIncomplete) {
...
struct sockaddr_in6 fromAddress;
...
}
########################BasicUDPSource.cpp#############################
在BasicUDPSource.cpp中:
void BasicUDPSource::incomingPacketHandler1(){
// Read the packet into our desired destination:
struct sockaddr_in6 fromAddress;
}
########################RTSPOverHTTPServer.cpp#############################
在RTSPOverHTTPServer.cpp中:
void RTSPOverHTTPServer::HTTPClientConnection::incomingRequestHandler1() {
struct sockaddr_in6 dummy; // 'from' address, meaningless in this case
}
########################RTSPClient.cpp#############################
在RTSPClient.cpp中:
...
//David fServerAddress(0)->fServerAddress(in6addr_any)
RTSPClient::RTSPClient(UsageEnvironment& env, char const* rtspURL,
int verbosityLevel, char const* applicationName,
portNumBits tunnelOverHTTPPortNum)
: Medium(env),
fVerbosityLevel(verbosityLevel), fCSeq(1),
fTunnelOverHTTPPortNum(tunnelOverHTTPPortNum), fUserAgentHeaderStr(NULL), fUserAgentHeaderStrLen(0),
fInputSocketNum(-1), fOutputSocketNum(-1), fServerAddress(in6addr_any), fBaseURL(NULL), fTCPStreamIdCount(0),
fLastSessionId(NULL), fSessionTimeoutParameter(0), fSessionCookieCounter(0), fHTTPTunnelingConnectionIsPending(False) {
...
}
/*****/
void RTSPClient::reset() {
...
fServerAddress = in6addr_any;
...
}
/*****/
unsigned RTSPClient::sendRequest(RequestRecord* request) {
//David
//unsigned connectionAddress = subsession.connectionEndpointAddress(); //修改如下
netAddressBits connectionAddress = subsession.connectionEndpointAddress();
netAddressBits in6addr0 = in6addr_any;
//Boolean requestMulticastStreaming
// = IsMulticastAddress(connectionAddress) || (connectionAddress == 0&& forceMulticastOnUnspecified);
Boolean requestMulticastStreaming
= IsMulticastAddress(connectionAddress) || (memcmp(&connectionAddress, &in6addr0, sizeof(in6addr0)) == 0 && forceMulticastOnUnspecified);
}
/*****/
Boolean RTSPClient::handleSETUPResponse(MediaSubsession& subsession, char const* sessionParamsStr, char const* transportParamsStr,
Boolean streamUsingTCP) {
...
//David
//if (destAddress == 0) destAddress = fServerAddress;
netAddressBits in6addr0 = in6addr_any;
if (memcmp(&destAddress, &in6addr0, sizeof(in6addr0)) == 0)
destAddress = fServerAddress;
...
}
/*****/
void RTSPClient::incomingDataHandler1() {
struct sockaddr_in6 dummy; // 'from' address - not used
...
}
########################SIPClient.hh#############################
在SIPClient.hh中:
class SIPClient: public Medium {
...
struct in6_addr fServerAddress;
...virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead,
struct sockaddr_in6& fromAddress) = 0;
}
########################SIPClient.cpp#############################
在SIPClient.cpp中:
SIPClient::SIPClient(UsageEnvironment& env,
unsigned char desiredAudioRTPPayloadFormat,
char const* mimeSubtype,
int verbosityLevel, char const* applicationName)...{
...
//struct in_addr ourAddress;
//ourAddress.s_addr = ourIPAddress(env); // hack
netAddressBits ourAddress;
ourAddress = ourIPAddress(env);
...
}
/*****/
unsigned SIPClient::getResponse(char*& responseBuffer,
unsigned responseBufferSize) {
...
struct sockaddr_in6 fromAddr;struct sockaddr_in6 fromAddr;
...
}
/*****/
void SIPClient::reset() {
...
//fServerAddress.s_addr = 0;
fServerAddress = in6addr_any;
...
}
/*****/
void SIPClient::setProxyServer(unsigned proxyServerAddress,
portNumBits proxyServerPortNum) {
//fServerAddress.s6_addr = proxyServerAddress; //David do
memcpy(&fServerAddress.s6_addr[0], &proxyServerAddress, 4);
}
########################GroupEId.hh#############################
在GroupEId.hh中
class GroupEId {
public:
GroupEId(struct in6_addr const& groupAddr,
portNumBits portNum, Scope const& scope,
unsigned numSuccessiveGroupAddrs = 1);
// used for a 'source-independent multicast' group
GroupEId(struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
portNumBits portNum,
unsigned numSuccessiveGroupAddrs = 1);
// used for a 'source-specific multicast' group
GroupEId(); // used only as a temp constructor prior to initialization
struct in6_addr const& groupAddress() const { return fGroupAddress; }
struct in6_addr const& sourceFilterAddress() const { return fSourceFilterAddress; }
...
private:
void init(struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
portNumBits portNum,
Scope const& scope,
unsigned numSuccessiveGroupAddrs);
private:
struct in6_addr fGroupAddress;
struct in6_addr fSourceFilterAddress;
...
}
########################GroupEId.cpp#############################
在GroupEId.cpp中
/*****/
GroupEId::GroupEId(struct in6_addr const& groupAddr,
portNumBits portNum, Scope const& scope,
unsigned numSuccessiveGroupAddrs) {
struct in6_addr sourceFilterAddr;
//David
//sourceFilterAddr.s_addr = ~0; // indicates no source filter
const char *buff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
netAddressBits in6addr1;
inet_pton(AF_INET6, buff, &in6addr1);
sourceFilterAddr = in6addr1;
...
}
/*****/
GroupEId::GroupEId(struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
portNumBits portNum,
unsigned numSuccessiveGroupAddrs) {
init(groupAddr, sourceFilterAddr, portNum, 255, numSuccessiveGroupAddrs);
}
/*****/
Boolean GroupEId::isSSM() const {
const char *buff = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
netAddressBits in6addr1;
inet_pton(AF_INET6, buff, &in6addr1);
return (memcmp(&fSourceFilterAddress, &in6addr1, sizeof(in6addr1)) != 0);
}
/*****/
void GroupEId::init(struct in6_addr const& groupAddr,
struct in6_addr const& sourceFilterAddr,
portNumBits portNum,
Scope const& scope,
unsigned numSuccessiveGroupAddrs) {
...
}
########################NetInterface.hh#############################
在NetInterface.hh中
class Socket: public NetInterface {
public:
virtual ~Socket();
virtual Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
unsigned& bytesRead,
struct sockaddr_in6& fromAddress) = 0;
}
########################MediaSession.hh#############################
在MediaSession.hh中
class MediaSession: public Medium {
public:
...
struct in6_addr const& sourceFilterAddr() const { return fSourceFilterAddr; }
...
protected:
...
struct in6_addr fSourceFilterAddr; // used for SSM
...
}
/*****/
class MediaSubsession {
PUBLIC:
...
Boolean isSSM() const { return fSourceFilterAddr.s6_addr != 0; }
...
protected:
...
struct in6_addr fSourceFilterAddr; // used for SSM
...
}
########################MediaSession.cpp#############################
在MediaSession.cpp中
...
MediaSession::MediaSession(UsageEnvironment& env):...{
//fSourceFilterAddr.s6_addr = {0};
memset(fSourceFilterAddr.s6_addr, 0, sizeof(fSourceFilterAddr.s6_addr));
...
}
...
static Boolean parseSourceFilterAttribute(char const* sdpLine, struct in6_addr& sourceAddr) {
...
//David
//if (sourceAddrBits == 0) break;
netAddressBits in6addr0 = in6addr_any;
if (memcmp(&sourceAddrBits, &in6addr0, sizeof(in6addr0)) == 0) break;
//sourceAddr.s_addr = sourceAd
...
}
...
/*****/
Boolean MediaSubsession::initiate(int useSpecialRTPoffset) {
...
//David
//struct in_addr tempAddr;
//tempAddr.s_addr = connectionEndpointAddress();
struct in6_addr tempAddr;
tempAddr = connectionEndpointAddress();
//if (fClientPortNum != 0 && (honorSDPPortChoice || IsMulticastAddress(tempAddr.s_addr))) {
if (fClientPortNum != 0 && (honorSDPPortChoice || IsMulticastAddress(tempAddr))) {
...
}
/*****/
netAddressBits MediaSubsession::connectionEndpointAddress() const {
...
//return 0;
return in6addr_any;
}
/*****/
void MediaSubsession::setDestinations(netAddressBits defaultDestAddress) {
...
//David
//if (destAddress == 0) destAddress = defaultDestAddress;
//struct in_addr destAddr; destAddr.s_addr = destAddress;
netAddressBits in6addr0 = in6addr_any;
if (memcmp(&destAddress, &in6add0, sizeof(in6addr0)) == 0)
destAddress = defaultDestAddress;
struct in6_addr destAddr;
destAddr = destAddress;
}
########################PassiveServerMediaSubsession.cpp#############################
在PassiveServerMediaSubsession.cpp中
...
void PassiveServerMediaSubsession
::getStreamParameters(unsigned clientSessionId,
netAddressBits clientAddress,
Port const& /*clientRTPPort*/,
Port const& clientRTCPPort,
int /*tcpSocketNum*/,
unsigned char /*rtpChannelId*/,
unsigned char /*rtcpChannelId*/,
netAddressBits& destinationAddress,
u_int8_t& destinationTTL,
Boolean& isMulticast,
Port& serverRTPPort,
Port& serverRTCPPort,
void*& streamToken) {
...
//if (destinationAddress == 0) { // normal case
//destinationAddress = gs.groupAddress().s_addr;
netAddressBits in6addr0 = in6addr_any;
if (memcmp(&destinationAddress, &in6addr0, sizeof(in6addr0))==0) { // normal case
destinationAddress = gs.groupAddress();
...
struct in6_addr destinationAddr; destinationAddr = destinationAddress;
...
}
########################OnDemandServerMediaSubsession.cpp#############################
在OnDemandServerMediaSubsession.cpp中
...
class Destinations {
public:
Destinations(struct in6_addr const& destAddr,
Port const& rtpDestPort,
Port const& rtcpDestPort)
: isTCP(False), addr(destAddr), rtpPort(rtpDestPort), rtcpPort(rtcpDestPort) {
}
...
public:
Boolean isTCP;
struct in6_addr addr;
...
}
/*****/
char const*
OnDemandServerMediaSubsession::sdpLines() {
...
//struct in_addr dummyAddr;
//dummyAddr.s_addr = 0;
struct in6_addr dummyAddr;
dummyAddr = in6addr_any;
...
}
/*****/
void OnDemandServerMediaSubsession
::getStreamParameters(unsigned clientSessionId,
netAddressBits clientAddress,
Port const& clientRTPPort,
Port const& clientRTCPPort,
int tcpSocketNum,
unsigned char rtpChannelId,
unsigned char rtcpChannelId,
netAddressBits& destinationAddress,
u_int8_t& /*destinationTTL*/,
Boolean& isMulticast,
Port& serverRTPPort,
Port& serverRTCPPort,
void*& streamToken) {
//David
//if (destinationAddress == 0) destinationAddress = clientAddress;
//struct in_addr destinationAddr; destinationAddr.s_addr = destinationAddress;
netAddressBits in6addr0 = in6addr_any;
if(memcmp(&destinationAddress, &in6adddr0, sizeof(in6addr0)) == 0)
destinationAddress = clientAddress;
struct in6_addr destinationAddr; destinationAddr = destinationAddress;
...
if (clientRTCPPort.num() == 0) {
..
//David
//struct in_addr dummyAddr; dummyAddr.s_addr = 0;
struct in6_addr dummyAddr;
dummyAddr = in6addr_any;
...
}else{
...
//David
//struct in_addr dummyAddr; dummyAddr.s_addr = 0;
struct in6_addr dummyAddr;
dummyAddr = in6addr_any;
...
}
}
/*****/
void OnDemandServerMediaSubsession
::setSDPLinesFromRTPSink(RTPSink* rtpSink, FramedSource* inputSource, unsigned estBitrate) {
...
//struct in_addr serverAddrForSDP; serverAddrForSDP.s_addr = fServerAddressForSDP;
struct in6_addr serverAddrForSDP; serverAddrForSDP = fServerAddressForSDP;
...
}
/*****/
void StreamState
::startPlaying(Destinations* dests,
TaskFunc* rtcpRRHandler, void* rtcpRRHandlerClientData,
ServerRequestAlternativeByteHandler* serverRequestAlternativeByteHandler,
void* serverRequestAlternativeByteHandlerClientData) {
...
//David
//fRTCPInstance->setSpecificRRHandler(dests->tcpSocketNum, dests->rtcpChannelId,
// rtcpRRHandler, rtcpRRHandlerClientData);
netAddressBits destsaddr;
memset(&destsaddr, 0, sizeof(destsaddr));
memcpy(&destsaddr, &dests->tcpSocketNum, 4);
fRTCPInstance->setSpecificRRHandler(destsaddr, dests->rtcpChannelId,
rtcpRRHandler, rtcpRRHandlerClientData);
...
}
/*****/
void StreamState::endPlaying(Destinations* dests) {
...
//David
//fRTCPInstance->setSpecificRRHandler(dests->tcpSocketNum, dests->rtcpChannelId,
// NULL, NULL);
netAddressBits destsaddr;
memset(&destsaddr, 0, sizeof(destsaddr));
memcpy(&destsaddr, &dests->tcpSocketNum, 4);
fRTCPInstance->setSpecificRRHandler(destsaddr, dests->rtcpChannelId,
NULL, NULL);
...
}
########################wis-streamer.cpp###########################
在wis-streamer.cpp中
...
int main(int argc, char** argv) {
...
//netAddressBits multicastAddress = our_inet_addr("239.6.6.6");
//David.milesight modify 14.06.05
netAddressBits multicastAddress;
inet_pton(AF_INET6, "ff0e::2", &multicastAddress);
...
//wyl.milesight.com add for multicast
if((video_type == VIDEO_TYPE_H264 || video_type == VIDEO_TYPE_H264_CIF || video_type == VIDEO_TYPE_H264_SVC_30FPS ||
video_type == VIDEO_TYPE_H264_SVC_15FPS || video_type == VIDEO_TYPE_H264_SVC_7FPS || video_type ==VIDEO_TYPE_H264_SVC_3FPS)&& atoi(argv[argc-1]) == 4&& nIsMulticastEnable)
{
//struct in_addr dest; dest.s_addr = multicastAddress; //David
struct in6_addr dest; dest.s_addr = multicastAddress;
...
}
...
}
...