📄 rvsocket.c
字号:
/*****************************************************************************
Filename : rvsocket.c
Description: Socket interface definition.
******************************************************************************
Copyright (c) 1999 RADVision Inc.
******************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision Inc.
No part of this publication may be reproduced in any form whatsoever
without written prior approval by RADVision Inc.
RADVision Inc. reserves the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
******************************************************************************
$Revision:$
$Date:$
$Author: S. Cipolli$
*****************************************************************************/
#include <string.h>
#include "rvplatform.h"
#include "rvlog.h"
#include "rvsocket_.h"
#include "rvsocket.h"
#include <stdio.h>
/* Ephemeral ports to check when searching for a free one */
#define PORT_START_SEARCH 49152
#define PORT_END_SEARCH 65535
#if defined(RV_SOCKETS_PSOS)
/* rename stuff for pSOS */
#define imr_multiaddr imr_mcastaddr
#endif
void rvSocketDestruct(RvSocket* s) {
rvLogEnter(&rvLog, "rvSocketDestruct");
rvSocketClose_(*s);
rvLogLeave(&rvLog, "rvSocketDestruct");
}
#if defined(RV_SOCKETS_NUCLEUS)
/* Only for nucleus, only called from rvSocketBind. See there for details. */
static RvBool rvSocketBindNucleusZero(RvSocket* s, const RvSocketAddr *addressPtr)
{
RvSocketAddr tryAddr;
RvInetPort port;
rvSocketAddrCopy(&tryAddr, addressPtr); /* use a copy to try ports with */
for(port = PORT_START_SEARCH; port <= PORT_END_SEARCH; port++) {
rvSocketAddrSetInetPort(&tryAddr, port);
if(rvSocketBind_(*s, &tryAddr) == 0)
return rvTrue;
}
return rvFalse;
}
#endif
RvBool rvSocketBind(RvSocket* s, const RvSocketAddr* addressPtr)
{
RvBool succeded = rvTrue;
rvLogEnter(&rvLog, "rvSocketBind");
#if defined(RV_SOCKETS_NUCLEUS)
if(rvSocketAddrGetInetPort(addressPtr) == 0) {
/* We need to deal with the fact that Nucleus does not */
/* handle binding to port 0. It does not assign a port */
/* at bind time even if the address is specified, so we */
/* have to search for it ourselves, just like in the */
/* rvSocketBindAnyPort function. */
succeded = rvSocketBindNucleusZero(s, addressPtr);
} else { /* do the normal bind */
#endif
/* Normal bind for everyone */
if(rvSocketBind_(*s, addressPtr) != 0)
succeded = rvFalse;
#if defined(RV_SOCKETS_NUCLEUS)
} /* Nucleus specific else */
#endif
#if (defined(RV_DEBUG_ON) && (RV_LOGMASK & RV_LOGLEVEL_ERROR))
if(succeded == rvFalse) {
char buffer[128];
char addrString[32];
int error = rvGetLastError();
rvSocketAddrToString(addressPtr,addrString);
sprintf(buffer,"RvSocket: Failed to Bind (Error = %i, %s ) to %s:%i.",
error, rvGetLastErrorAsString(error), addrString,
rvSocketAddrGetInetPort(addressPtr));
rvLogError(&rvLog,buffer);
} else {
char buffer[128];
char addrString[32];
rvSocketAddrToString(addressPtr,addrString);
sprintf(buffer,"RvSocket: Bound to %s:%i.",
addrString, rvSocketAddrGetInetPort(addressPtr));
rvLogInfo4(&rvLog,buffer);
}
#endif
rvLogLeave(&rvLog, "rvSocketBind");
return succeded;
}
/* If we need to force port selection for an anyaddress anyport bind */
RvBool rvSocketBindAnyPort(RvSocket* s, RvSocketAddr *localAddr) {
RvBool succeded = rvFalse;
RvInetPort port;
rvLogEnter(&rvLog, "rvSocketBindAnyPort");
for(port = PORT_START_SEARCH; port <= PORT_END_SEARCH; port++) {
rvSocketAddrSetInetPort(localAddr, port);
if(rvSocketBind_(*s, localAddr) == 0) {
succeded = rvTrue;
break;
}
}
if(succeded == rvFalse) {
#if (defined(RV_DEBUG_ON) && (RV_LOGMASK & RV_LOGLEVEL_ERROR))
char buffer[128];
int error = rvGetLastError();
sprintf(buffer,"RvSocket: Failed to find port to Bind (Error = %i, %s ).",
error, rvGetLastErrorAsString(error));
rvLogError(&rvLog,buffer);
#endif
} else {
#if (RV_LOGMASK & RV_LOGLEVEL_INFO4)
char buffer[256];
char addrString[32];
rvSocketAddrToString(localAddr,addrString);
sprintf(buffer,"RvSocket: Bound to %s:%i.",
addrString, rvSocketAddrGetInetPort(localAddr));
rvLogInfo4(&rvLog,buffer);
#endif
}
rvLogLeave(&rvLog, "rvSocketBindAnyPort");
return succeded;
}
RvSocketAddr* rvSocketGetLocalAddr(RvSocket* s, RvSocketAddr* addr) {
if (!rvSocketGetSockName_(*s, addr ))
return NULL;
return addr;
}
/* Convenience function; not exactly address independent, but useful */
RvInetPort rvSocketGetPort(RvSocket* s)
{
RvSocketAddr addr;
RvInetPort port;
rvSocketAddrConstruct(&addr);
if(!rvSocketGetSockName_(*s, &addr))
return 0;
port = rvSocketAddrGetInetPort(&addr);
rvSocketAddrDestruct(&addr);
return port;
}
RvBool rvSocketSetMulticastInterface(RvSocket* s, RvUint32 ipaddr) {
struct in_addr addr;
RvBool setInterface = rvFalse;
addr.s_addr = ipaddr;
#if defined(IP_MULTICAST_IF)
setInterface = (rvSocketSetSockOpt_(*s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&addr, sizeof(addr)) == 0);
#if (defined(RV_DEBUG_ON) && (RV_LOGMASK & (RV_LOGLEVEL_INFO4|RV_LOGLEVEL_ERROR)))
{
char buffer[256];
char addrbuf[16];
int offset;
int error = rvGetLastError();
offset = sprintf(buffer,"RvSocket(Port = %i): ", rvSocketGetPort(s));
if(setInterface)
offset += sprintf(&buffer[offset],"Set multicast interface to ");
else
offset += sprintf(&buffer[offset],"Failed to set multicast interface (Error = %i, %s ) to ", error, rvGetLastErrorAsString(error));
#if defined(RV_SOCKETS_NUCLEUS)
offset += sprintf(&buffer[offset],"%s:", rvInetNtoa(addr.sck_ip_addr, addrbuf));
#else
offset += sprintf(&buffer[offset],"%s:", rvInetNtoa(addr, addrbuf));
#endif
offset += sprintf(&buffer[offset],".");
if(setInterface)
rvLogInfo4(&rvLog,buffer);
else
rvLogError(&rvLog,buffer);
}
#endif
#endif
return setInterface;
}
RvBool rvSocketSetMulticastLoop(RvSocket* s, RvBool loop) {
RvBool loopSet = rvFalse;
#if defined(RV_INET_IPV6)
#if defined(IPV6_MULTICAST_LOOP)
unsigned int loopback = loop ? 1 : 0; /* IPv6 requires a int size value */
loopSet = (rvSocketSetSockOpt_(*s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*)&loopback, sizeof(loopback)) == 0);
#endif
#else
#if defined(IP_MULTICAST_LOOP)
unsigned char loopback = loop ? 1 : 0; /* IPv4 requires a char size value */
loopSet = (rvSocketSetSockOpt_(*s, IPPROTO_IP, IP_MULTICAST_LOOP, (char*)&loopback, sizeof(loopback)) == 0);
#endif
#endif
#if (defined(RV_DEBUG_ON) && (RV_LOGMASK & RV_LOGLEVEL_ERROR))
if(!loopSet)
{
char buffer[128];
int error = rvGetLastError();
sprintf(buffer,"RvSocket(Port = %i): Failed to set multicast loop %s (Error = %i, %s).", rvSocketGetPort(s), loop ? "on" : "off", error, rvGetLastErrorAsString(error));
rvLogError(&rvLog,buffer);
}
#endif
return loopSet;
}
RvBool rvSocketGetMulticastLoop(RvSocket* s, RvBool* loop) {
RvBool succeeded = rvFalse;
int size;
#if defined(RV_INET_IPV6)
#if defined(IPV6_MULTICAST_LOOP)
unsigned int loopback; /* IPv6 requires a int size value */
size = sizeof(loopback);
succeeded = (rvSocketGetSockOpt_(*s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char*)&loopback, &size) == 0);
*loop = (loopback == 0) ? rvFalse : rvTrue;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -