live555修改网络模块,支持IPv6的访问和传输

      一. 背景

           因为项目的需求,针对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;
            ...
    }
    ...
}
...

      


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值