Exemplo n.º 1
0
static void ConnectThread( void *arg )
{
    PRStatus    rv;
    PRFileDesc  *clientSock;
    PRNetAddr   serverAddress;
    clientSock = PR_NewTCPSocket();

    PR_ASSERT(clientSock);

    if ( resume ) {
        if ( debug ) printf("pausing 3 seconds before connect\n");
        PR_Sleep( PR_SecondsToInterval(3));
    }

    memset(&serverAddress, 0, sizeof(serverAddress));
    rv = PR_InitializeNetAddr(PR_IpAddrLoopback, BASE_PORT, &serverAddress);
    PR_ASSERT( PR_SUCCESS == rv );
    rv = PR_Connect( clientSock, 
        &serverAddress, 
        PR_SecondsToInterval(1));
    PR_ASSERT( PR_SUCCESS == rv );

    /* that's all we do. ... Wait for the acceptread() to timeout */
    while( state != AllDone )
        PR_Sleep( PR_SecondsToInterval(1));
    return;
} /* end ConnectThread() */
Exemplo n.º 2
0
static PRStatus
nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime to)
{
    PRStatus status;
    PRNetAddr dst;

    nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret;
    if (info == NULL) return PR_FAILURE;

    if (PR_NetAddrFamily(addr) == PR_AF_INET6 &&
        PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) {
        const uint8_t *srcp;

        LOGDEBUG(("socks: converting ipv4-mapped ipv6 address to ipv4"));

        // copied from _PR_ConvertToIpv4NetAddr()
        PR_InitializeNetAddr(PR_IpAddrAny, 0, &dst);
        srcp = addr->ipv6.ip.pr_s6_addr;
        memcpy(&dst.inet.ip, srcp + 12, 4);
        dst.inet.family = PR_AF_INET;
        dst.inet.port = addr->ipv6.port;
    } else {
        memcpy(&dst, addr, sizeof(dst));
    }

    info->SetDestinationAddr(&dst);
    info->SetConnectTimeout(to);

    do {
        status = info->DoHandshake(fd, -1);
    } while (status == PR_SUCCESS && !info->IsConnected());

    return status;
}
int main(int argc, char **argv)
{
    PRFileDesc *listenSock;
    PRThread *clientThread;
    PRThread *serverThread;
    PRNetAddr addr;
    PRThreadScope scope = PR_GLOBAL_THREAD;

    listenSock = PR_NewTCPSocket();
    if (NULL == listenSock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_Bind(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_Bind failed\n");
        exit(1);
    }
    /* Find out what port number we are bound to. */
    if (PR_GetSockName(listenSock, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_GetSockName failed\n");
        exit(1);
    }
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
        fprintf(stderr, "PR_Listen failed\n");
        exit(1);
    }

    clientThread = PR_CreateThread(PR_USER_THREAD,
            ClientThread, (void *) PR_ntohs(PR_NetAddrInetPort(&addr)),
            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
    if (NULL == clientThread) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    serverThread = PR_CreateThread(PR_USER_THREAD,
            ServerThread, listenSock,
            PR_PRIORITY_NORMAL, scope, PR_JOINABLE_THREAD, 0);
    if (NULL == serverThread) {
        fprintf(stderr, "PR_CreateThread failed\n");
        exit(1);
    }
    if (PR_JoinThread(clientThread) == PR_FAILURE) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    if (PR_JoinThread(serverThread) == PR_FAILURE) {
        fprintf(stderr, "PR_JoinThread failed\n");
        exit(1);
    }
    if (PR_Close(listenSock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
    printf("PASS\n");
    return 0;
}
Exemplo n.º 4
0
// returns 0 on success, non-zero on error
int
DoCallback()
{
  UniquePRFileDesc socket(PR_NewTCPSocket());
  if (!socket) {
    PrintPRError("PR_NewTCPSocket failed");
    return 1;
  }

  PRNetAddr addr;
  PR_InitializeNetAddr(PR_IpAddrLoopback, gCallbackPort, &addr);
  if (PR_Connect(socket.get(), &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) {
    PrintPRError("PR_Connect failed");
    return 1;
  }

  const char *request = "GET / HTTP/1.0\r\n\r\n";
  SendAll(socket.get(), request, strlen(request));
  char buf[4096];
  memset(buf, 0, sizeof(buf));
  int32_t bytesRead = PR_Recv(socket.get(), buf, sizeof(buf) - 1, 0,
                              PR_INTERVAL_NO_TIMEOUT);
  if (bytesRead < 0) {
    PrintPRError("PR_Recv failed 1");
    return 1;
  }
  if (bytesRead == 0) {
    fprintf(stderr, "PR_Recv eof 1\n");
    return 1;
  }
  fprintf(stderr, "%s\n", buf);
  return 0;
}
Exemplo n.º 5
0
nsresult UDPSocketParent::ConnectInternal(const nsCString& aHost,
                                          const uint16_t& aPort) {
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  if (!mSocket) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  PRNetAddr prAddr;
  memset(&prAddr, 0, sizeof(prAddr));
  PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
  PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
  if (status != PR_SUCCESS) {
    return NS_ERROR_FAILURE;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);

  rv = mSocket->Connect(&addr);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  return NS_OK;
}
Exemplo n.º 6
0
nsSOCKSSocketInfo::nsSOCKSSocketInfo()
    : mState(SOCKS_INITIAL)
    , mDataIoPtr(nullptr)
    , mDataLength(0)
    , mReadOffset(0)
    , mAmountToRead(0)
    , mProxyPort(-1)
    , mVersion(-1)
    , mDestinationFamily(PR_AF_INET)
    , mFlags(0)
    , mTimeout(PR_INTERVAL_NO_TIMEOUT)
{
    mData = new uint8_t[BUFFER_SIZE];
    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mInternalProxyAddr);
    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mExternalProxyAddr);
    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mDestinationAddr);
}
Exemplo n.º 7
0
// callback while UDP socket is opened or closed
NS_IMETHODIMP NrSocketIpc::CallListenerVoid(const nsACString &type) {
  ASSERT_ON_THREAD(main_thread_);
  if (type.EqualsLiteral("onopen")) {
    ReentrantMonitorAutoEnter mon(monitor_);

    uint16_t port;
    if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to get local port");
      return NS_OK;
    }

    nsAutoCString address;
    if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to get local address");
      return NS_OK;
    }

    PRNetAddr praddr;
    if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
      return NS_OK;
    }

    if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
      return NS_OK;
    }

    nr_transport_addr expected_addr;
    if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to copy my_addr_");
    }

    if (nr_praddr_to_transport_addr(&praddr, &my_addr_, 1)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
    }

    if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
                              NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
      err_ = true;
      MOZ_ASSERT(false, "Address of opened socket is not expected");
    }

    mon.NotifyAll();
  } else if (type.EqualsLiteral("onclose")) {
    // Already handled in UpdateReadyState, nothing to do here
  } else {
    MOZ_ASSERT(false, "Received unexpected event");
  }

  return NS_OK;
}
Exemplo n.º 8
0
bool
UDPSocketParent::Init(const nsCString &aHost, const uint16_t aPort)
{
  nsresult rv;
  NS_ASSERTION(mFilter, "No packet filter");

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      FireInternalError(this, __LINE__);
      return true;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr);
  }

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  mSocket = sock;

  net::NetAddr localAddr;
  mSocket->GetAddress(&localAddr);

  uint16_t port;
  nsCString addr;
  rv = ConvertNetAddrToString(localAddr, &addr, &port);

  if (NS_FAILED(rv)) {
    FireInternalError(this, __LINE__);
    return true;
  }

  // register listener
  mSocket->AsyncListen(this);
  mozilla::unused <<
      PUDPSocketParent::SendCallback(NS_LITERAL_CSTRING("onopen"),
                                     UDPAddressInfo(addr, port),
                                     NS_LITERAL_CSTRING("connected"));

  return true;
}
Exemplo n.º 9
0
RCNetAddr::RCNetAddr(RCNetAddr::HostValue host, PRUint16 port): RCBase()
{
    PRNetAddrValue how;
    switch (host)
    {
        case RCNetAddr::any: how = PR_IpAddrAny; break;
        case RCNetAddr::loopback: how = PR_IpAddrLoopback; break;
        default: PR_NOT_REACHED("This can't happen -- and did!");
    }
    (void)PR_InitializeNetAddr(how, port, &address);
}  /* RCNetAddr::RCNetAddr */
Exemplo n.º 10
0
// callback while UDP socket is opened
NS_IMETHODIMP NrSocketIpc::CallListenerOpened() {
  ASSERT_ON_THREAD(main_thread_);
  ReentrantMonitorAutoEnter mon(monitor_);

  uint16_t port;
  if (NS_FAILED(socket_child_->GetLocalPort(&port))) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to get local port");
    return NS_OK;
  }

  nsAutoCString address;
  if(NS_FAILED(socket_child_->GetLocalAddress(address))) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to get local address");
    return NS_OK;
  }

  PRNetAddr praddr;
  if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, port, &praddr)) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
    return NS_OK;
  }

  if (PR_SUCCESS != PR_StringToNetAddr(address.BeginReading(), &praddr)) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to convert local host to PRNetAddr");
    return NS_OK;
  }

  nr_transport_addr expected_addr;
  if(nr_transport_addr_copy(&expected_addr, &my_addr_)) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to copy my_addr_");
  }

  if (nr_praddr_to_transport_addr(&praddr, &my_addr_, IPPROTO_UDP, 1)) {
    err_ = true;
    MOZ_ASSERT(false, "Failed to copy local host to my_addr_");
  }

  if (nr_transport_addr_cmp(&expected_addr, &my_addr_,
                            NR_TRANSPORT_ADDR_CMP_MODE_ADDR)) {
    err_ = true;
    MOZ_ASSERT(false, "Address of opened socket is not expected");
  }

  mon.NotifyAll();

  return NS_OK;
}
Exemplo n.º 11
0
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, nsCString(aHost).get(), aPort));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  rv = sock->SetMulticastLoopback(aLoopback);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}
static void ClientThread(void *arg)
{
    PRFileDesc *sock;
    PRNetAddr addr;
    PRUint16 port = (PRUint16) arg;
    char buf[1024];
    char *bufPtr;
    PRInt32 nbytes;
    PRInt32 ntotal;
    PRInt32 nexpected;

    sock = PR_NewTCPSocket();
    if (NULL == sock) {
        fprintf(stderr, "PR_NewTCPSocket failed\n");
        exit(1);
    }
    if (PR_InitializeNetAddr(PR_IpAddrLoopback, port, &addr) == PR_FAILURE) {
        fprintf(stderr, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_Connect(sock, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
        fprintf(stderr, "PR_Connect failed\n");
        exit(1);
    }
    ntotal = 0;
    bufPtr = buf;
    while ((nbytes = PR_Read(sock, bufPtr, sizeof(buf)-ntotal)) > 0) {
        ntotal += nbytes;
        bufPtr += nbytes;
    }
    if (-1 == nbytes) {
        fprintf(stderr, "PR_Read failed\n");
        exit(1);
    }
    nexpected = HEADER_LEN+TRAILER_LEN+TRAILER_LEN+HEADER_LEN+HEADER_LEN;
    if (ntotal != nexpected) {
        fprintf(stderr, "total bytes read should be %d but is %d\n",
                nexpected, ntotal);
        exit(1);
    }
    if (memcmp(buf, HEADER_STR TRAILER_STR TRAILER_STR HEADER_STR HEADER_STR,
            nexpected) != 0) {
        fprintf(stderr, "wrong data is received\n");
        exit(1);
    }
    if (PR_Close(sock) == PR_FAILURE) {
        fprintf(stderr, "PR_Close failed\n");
        exit(1);
    }
}
Exemplo n.º 13
0
PRStatus
initAddr (PRNetAddr* addr, const char* host, int port = -1)
{
    std::string sHost = host;
 
    if (PR_StringToNetAddr(sHost.c_str(), addr) == PR_FAILURE) {
        std::string sIp;
        std::string sPort;
 
        if (sHost[0] == '[') {
            sIp = sHost.substr(1, sHost.find_last_of("]")-1);
            sPort = sHost.substr(sHost.find_last_of("]")+2);
        }
        else {
            sIp = sHost.substr(0, sHost.find_last_of(":"));
            sPort = sHost.substr(sHost.find_last_of(":")+1);
        }

        if (!sPort.empty()) {
            int tmp = atoi(sPort.c_str());

            if (tmp >= 1 && tmp <= 65536) {
                port = tmp;
            }
        }
 
        if (PR_StringToNetAddr(sIp.c_str(), addr) == PR_FAILURE) {
            char* ip = getHostByName(sIp.c_str());

            if (ip == NULL) {
                return PR_FAILURE;
            }

            sIp = ip; delete [] ip;
 
            if (PR_StringToNetAddr(sIp.c_str(), addr) == PR_FAILURE) {
                return PR_FAILURE;
            }
        }
    }
 
    if (port >= 1 && port <= 65536) {
        PR_InitializeNetAddr(PR_IpAddrNull, port, addr);
    }
 
    return PR_SUCCESS;
}
Exemplo n.º 14
0
static void Server(void)
{
    PRStatus rv;
    PRNetAddr server_address, client_address;
    PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);

    if (NULL == xport)
    {
        PL_FPrintError(err, "PR_Socket");
        return;
    }

    rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
    if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
    else
    {
        rv = PR_Bind(xport, &server_address);
        if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
        else
        {
            PRFileDesc *client;
            rv = PR_Listen(xport, 10);
            PR_fprintf(err, "Server listening on ");
            (void)PrintAddress(&server_address);
            do
            {
                client = PR_Accept(
                    xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
                if (NULL == client) PL_FPrintError(err, "PR_Accept");
                else
                {
                    PR_fprintf(err, "Server accepting from ");
                    (void)PrintAddress(&client_address);
                    shared->threads += 1;
                    (void)PR_CreateThread(
                        PR_USER_THREAD, Servette, client,
                        PR_PRIORITY_NORMAL, thread_scope,
                        PR_UNJOINABLE_THREAD, 8 * 1024);
                }
            } while (PR_TRUE);

        }
    }
}  /* Server */
Exemplo n.º 15
0
int ConfigServerSocket() {

  /* Set up Net address to bind to 'any' */
  int r;
 
  r = PR_InitializeNetAddr(PR_IpAddrAny,0,&svr.na);
  if (PR_SUCCESS != r) return Error(2);

  
  r = PR_Bind(svr.r,&svr.na);     /* bind to an IP address */
  if (PR_SUCCESS != r) return Error(3);


  r = PR_Listen(svr.r,5);
  if (PR_SUCCESS != r) return Error(4);


  r = PR_GetSockName(svr.r,&svr.na);
  if (PR_SUCCESS != r) return Error(5);
  return r;
}
int main(int argc, char **argv)
{
    PRStatus rv;
    PRFileDesc *udp = PR_NewUDPSocket();
    PRFileDesc *tcp = PR_NewTCPSocket();
    const char *tag[] =
    {
        "PR_SockOpt_Nonblocking",     /* nonblocking io */
        "PR_SockOpt_Linger",          /* linger on close if data present */
        "PR_SockOpt_Reuseaddr",       /* allow local address reuse */
        "PR_SockOpt_Keepalive",       /* keep connections alive */
        "PR_SockOpt_RecvBufferSize",  /* send buffer size */
        "PR_SockOpt_SendBufferSize",  /* receive buffer size */

        "PR_SockOpt_IpTimeToLive",    /* time to live */
        "PR_SockOpt_IpTypeOfService", /* type of service and precedence */

        "PR_SockOpt_AddMember",       /* add an IP group membership */
        "PR_SockOpt_DropMember",      /* drop an IP group membership */
        "PR_SockOpt_McastInterface",  /* multicast interface address */
        "PR_SockOpt_McastTimeToLive", /* multicast timetolive */
        "PR_SockOpt_McastLoopback",   /* multicast loopback */

        "PR_SockOpt_NoDelay",         /* don't delay send to coalesce packets */
        "PR_SockOpt_MaxSegment",      /* maximum segment size */
        "PR_SockOpt_Broadcast",       /* Enable broadcast */
        "PR_SockOpt_Last"
    };

    err = PR_GetSpecialFD(PR_StandardError);
    PR_STDIO_INIT();

    if (NULL == udp) Failed("PR_NewUDPSocket()", NULL);
    else if (NULL == tcp) Failed("PR_NewTCPSocket()", NULL);
    else
    {
        PRSockOption option;
        PRUint32 segment = 1024;
        PRNetAddr addr;

        rv = PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr);
        if (PR_FAILURE == rv) Failed("PR_InitializeNetAddr()", NULL);
        rv = PR_Bind(udp, &addr);
        if (PR_FAILURE == rv) Failed("PR_Bind()", NULL);
        for(option = PR_SockOpt_Linger; option < PR_SockOpt_Last; Incr(&option))
        {
            PRSocketOptionData data;
            PRFileDesc *fd = tcp;
            data.option = option;
            switch (option)
            {
                case PR_SockOpt_Nonblocking:
                    data.value.non_blocking = PR_TRUE;
                    break;    
#ifndef SYMBIAN
                case PR_SockOpt_Linger:
                    data.value.linger.polarity = PR_TRUE;
                    data.value.linger.linger = PR_SecondsToInterval(2);          
                    break;    
#endif
                case PR_SockOpt_Reuseaddr:
                    data.value.reuse_addr = PR_TRUE;      
                    break;    
                case PR_SockOpt_Keepalive:       
                    data.value.keep_alive = PR_TRUE;      
                    break;    
                case PR_SockOpt_RecvBufferSize:
                    data.value.recv_buffer_size = segment;  
                    break;    
                case PR_SockOpt_SendBufferSize:  
                    data.value.send_buffer_size = segment;  
                    break;    
#ifndef SYMBIAN
                case PR_SockOpt_IpTimeToLive:
                    data.value.ip_ttl = 64;  
                    break;    
                case PR_SockOpt_IpTypeOfService:
                    data.value.tos = 0; 
                    break;    
                case PR_SockOpt_McastTimeToLive:
                    fd = udp; 
                    data.value.mcast_ttl = 4; 
                    break;    
                case PR_SockOpt_McastLoopback:
                    fd = udp; 
                    data.value.mcast_loopback = PR_TRUE; 
                    break;    
#endif
                case PR_SockOpt_NoDelay:
                    data.value.no_delay = PR_TRUE;         
                    break;    
#ifndef WIN32
                case PR_SockOpt_MaxSegment:
                    data.value.max_segment = segment;      
                    break;    
#endif
#ifndef SYMBIAN
                case PR_SockOpt_Broadcast:
                    fd = udp; 
                    data.value.broadcast = PR_TRUE;         
                    break;    
#endif
                default: continue;
            }

			/*
			 * TCP_MAXSEG can only be read, not set
			 */
            if (option != PR_SockOpt_MaxSegment) {
#ifdef WIN32
            	if (option != PR_SockOpt_McastLoopback)
#endif
				{
            		rv = PR_SetSocketOption(fd, &data);
            		if (PR_FAILURE == rv)
							Failed("PR_SetSocketOption()", tag[option]);
				}
			}

            rv = PR_GetSocketOption(fd, &data);
            if (PR_FAILURE == rv) Failed("PR_GetSocketOption()", tag[option]);
        }
        PR_Close(udp);
        PR_Close(tcp);
    }
    PR_fprintf(err, "%s\n", (failed) ? "FAILED" : "PASSED");
    return (failed) ? 1 : 0;
}  /* main */
Exemplo n.º 17
0
PRIntn main(PRIntn argc, char **argv)
{
    PRStatus rv;
    PRIntn mits;
    PLOptStatus os;
    PRFileDesc *client, *service;
    PRFileDesc *client_stack, *service_stack;
    PRNetAddr any_address;
    const char *server_name = NULL;
    const PRIOMethods *stubMethods;
    PRThread *client_thread, *server_thread;
    PRThreadScope thread_scope = PR_LOCAL_THREAD;
    PLOptState *opt = PL_CreateOptState(argc, argv, "dqGC:c:p:");
    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 0:
            server_name = opt->value;
            break;
        case 'd':  /* debug mode */
            if (verbosity < noisy)
                verbosity = ChangeVerbosity(verbosity, 1);
            break;
        case 'q':  /* debug mode */
            if (verbosity > silent)
                verbosity = ChangeVerbosity(verbosity, -1);
            break;
        case 'G':  /* use global threads */
            thread_scope = PR_GLOBAL_THREAD;
            break;
        case 'C':  /* number of threads waiting */
            major_iterations = atoi(opt->value);
            break;
        case 'c':  /* number of client threads */
            minor_iterations = atoi(opt->value);
            break;
        case 'p':  /* default port */
            default_port = atoi(opt->value);
            break;
        default:
            break;
        }
    }
    PL_DestroyOptState(opt);
    PR_STDIO_INIT();

    logFile = PR_GetSpecialFD(PR_StandardError);

    identity = PR_GetUniqueIdentity("Dummy");
    stubMethods = PR_GetDefaultIOMethods();

    /*
    ** The protocol we're going to implement is one where in order to initiate
    ** a send, the sender must first solicit permission. Therefore, every
    ** send is really a send - receive - send sequence.
    */
    myMethods = *stubMethods;  /* first get the entire batch */
    myMethods.recv = MyRecv;  /* then override the ones we care about */
    myMethods.send = MySend;  /* then override the ones we care about */

    if (NULL == server_name)
        rv = PR_InitializeNetAddr(
            PR_IpAddrLoopback, default_port, &server_address);
    else
    {
        rv = PR_StringToNetAddr(server_name, &server_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_InitializeNetAddr(
            PR_IpAddrNull, default_port, &server_address);
    }
    PR_ASSERT(PR_SUCCESS == rv);

    /* one type w/o layering */

    mits = minor_iterations;
    while (major_iterations-- > 0)
    {
        if (verbosity > silent)
            PR_fprintf(logFile, "Beginning non-layered test\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
        if (verbosity > silent)
            PR_fprintf(logFile, "Ending non-layered test\n");

        /* with layering */
        if (verbosity > silent)
            PR_fprintf(logFile, "Beginning layered test\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
        PushLayer(client);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
        PushLayer(service);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service); PR_ASSERT(PR_SUCCESS == rv);
        /* with layering, using new style stack */
        if (verbosity > silent)
            PR_fprintf(logFile,
							"Beginning layered test with new style stack\n");
        client = PR_NewTCPSocket(); PR_ASSERT(NULL != client);
    	client_stack = PR_CreateIOLayer(client);
        PushNewLayers(client_stack);
        service = PR_NewTCPSocket(); PR_ASSERT(NULL != service);
    	service_stack = PR_CreateIOLayer(service);
        PushNewLayers(service_stack);
        rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &any_address);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Bind(service, &any_address); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Listen(service, 10); PR_ASSERT(PR_SUCCESS == rv);

        minor_iterations = mits;
        server_thread = PR_CreateThread(
            PR_USER_THREAD, Server, service_stack,
            PR_PRIORITY_HIGH, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != server_thread);

        client_thread = PR_CreateThread(
            PR_USER_THREAD, Client, client_stack,
            PR_PRIORITY_NORMAL, thread_scope,
            PR_JOINABLE_THREAD, 16 * 1024);
        PR_ASSERT(NULL != client_thread);

        rv = PR_JoinThread(client_thread);
        PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_JoinThread(server_thread);
        PR_ASSERT(PR_SUCCESS == rv);

        rv = PR_Close(client_stack); PR_ASSERT(PR_SUCCESS == rv);
        rv = PR_Close(service_stack); PR_ASSERT(PR_SUCCESS == rv);
        if (verbosity > silent)
            PR_fprintf(logFile, "Ending layered test\n");
    }
    return 0;
}  /* main */
Exemplo n.º 18
0
int main(int argc, char **argv)
{
    PRHostEnt he;
    PRStatus status;
    PRIntn next_index;
    PRUint16 port_number;
    char netdb_buf[PR_NETDB_BUF_SIZE];
    PRNetAddr client_addr, server_addr;
    PRThread *client_thread, *server_thread;
    PRIntervalTime delta = PR_MillisecondsToInterval(500);

    err_out = PR_STDERR;
    std_out = PR_STDOUT;
    accept_timeout = PR_SecondsToInterval(2);
    emu_layer_ident = PR_GetUniqueIdentity("Emulated AcceptRead");
    emu_layer_methods = *PR_GetDefaultIOMethods();
    emu_layer_methods.acceptread = emu_AcceptRead;

    if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
    else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);

    status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
    if (PR_SUCCESS != status)
    {
        PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
        PR_ProcessExit(1);
    }
    if (argc < 3)
    {
        status = PR_InitializeNetAddr(
            PR_IpAddrLoopback, port_number, &client_addr);
        if (PR_SUCCESS != status)
        {
            PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
            PR_ProcessExit(1);
        }
    }
    else
    {
        status = PR_GetHostByName(
            argv[1], netdb_buf, sizeof(netdb_buf), &he);
        if (status == PR_FAILURE)
        {
            PL_FPrintError(err_out, "PR_GetHostByName failed");
            PR_ProcessExit(1);
        }
        next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
        if (next_index == -1)
        {
            PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
            PR_ProcessExit(1);
        }
    }

    for (
        write_dally = 0;
        write_dally < accept_timeout + (2 * delta);
        write_dally += delta)
    {
        PR_fprintf(
            std_out, "Testing w/ write_dally = %d msec\n",
            PR_IntervalToMilliseconds(write_dally));
        server_thread = PR_CreateThread(
            PR_USER_THREAD, AcceptingThread, &server_addr,
            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
        if (server_thread == NULL)
        {
            PL_FPrintError(err_out, "PR_CreateThread (server) failed");
            PR_ProcessExit(1);
        }

        PR_Sleep(delta);  /* let the server pot thicken */

        client_thread = PR_CreateThread(
            PR_USER_THREAD, ConnectingThread, &client_addr,
            PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
        if (client_thread == NULL)
        {
            PL_FPrintError(err_out, "PR_CreateThread (client) failed");
            PR_ProcessExit(1);
        }

        if (PR_JoinThread(client_thread) == PR_FAILURE)
            PL_FPrintError(err_out, "PR_JoinThread (client) failed");

        if (PR_JoinThread(server_thread) == PR_FAILURE)
            PL_FPrintError(err_out, "PR_JoinThread (server) failed");
    }

    return 0;
}
Exemplo n.º 19
0
PRIntn main(PRIntn argc, char *argv[])
{
    PRThread *tJitter;
    PRThread *tAccept;
    PRThread *tConnect;
    PRStatus rv;
    /* This test if valid for WinNT only! */

#if !defined(WINNT)
    return 0;
#endif

    {
        /*
        ** Get command line options
        */
        PLOptStatus os;
        PLOptState *opt = PL_CreateOptState(argc, argv, "hdrvj:");

	    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
        {
		    if (PL_OPT_BAD == os) continue;
            switch (opt->option)
            {
            case 'd':  /* debug */
                debug = 1;
			    msgLevel = PR_LOG_ERROR;
                break;
            case 'v':  /* verbose mode */
                verbose = 1;
			    msgLevel = PR_LOG_DEBUG;
                break;
            case 'j':
                jitter = atoi(opt->value);
                if ( jitter == 0)
                    jitter = JITTER_DEFAULT;
                break;
            case 'r':
                resume = PR_TRUE;
                break;
            case 'h':  /* help message */
			    Help();
                break;
             default:
                break;
            }
        }
	    PL_DestroyOptState(opt);
    }

    lm = PR_NewLogModule("Test");       /* Initialize logging */

    /* set concurrency */
    PR_SetConcurrency( 4 );

    /* setup thread synchronization mechanics */
    ml = PR_NewLock();
    cv = PR_NewCondVar( ml );

    /* setup a tcp socket */
    memset(&listenAddr, 0, sizeof(listenAddr));
    rv = PR_InitializeNetAddr(PR_IpAddrAny, BASE_PORT, &listenAddr);
    PR_ASSERT( PR_SUCCESS == rv );

    listenSock = PR_NewTCPSocket();
    PR_ASSERT( listenSock );

    rv = PR_Bind( listenSock, &listenAddr);
    PR_ASSERT( PR_SUCCESS == rv );

    rv = PR_Listen( listenSock, 5 );
    PR_ASSERT( PR_SUCCESS == rv );

    /* open a file for writing, provoke bug */
    file1 = PR_Open("xxxTestFile", PR_CREATE_FILE | PR_RDWR, 666);

    /* create Connect thread */
    tConnect = PR_CreateThread(
        PR_USER_THREAD, ConnectThread, NULL,
        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tConnect );

    /* create jitter off thread */
    tJitter = PR_CreateThread(
        PR_USER_THREAD, JitterThread, NULL,
        PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tJitter );

    /* create acceptread thread */
    tAccept = PR_CreateThread(
        PR_USER_THREAD, AcceptThread, NULL,
        PR_PRIORITY_NORMAL, PR_LOCAL_THREAD,
        PR_JOINABLE_THREAD, 0 );
    PR_ASSERT( tAccept );

    /* wait for all threads to quit, then terminate gracefully */
    PR_JoinThread( tConnect );
    PR_JoinThread( tAccept );
    PR_JoinThread( tJitter );
    PR_Close( listenSock );
    PR_DestroyCondVar(cv);
    PR_DestroyLock(ml);
    PR_Close( file1 );
    PR_Delete( "xxxTestFile");

    /* test return and exit */
    if (debug) printf("%s\n", (failed_already)? "FAIL" : "PASS");
    return( (failed_already == PR_TRUE )? 1 : 0 );
}  /* main() */
Exemplo n.º 20
0
static bool NewTCPSocketPair(PRFileDesc *fd[])
{
  // this is a replacement for PR_NewTCPSocketPair that manually
  // sets the recv buffer to 64K. A windows bug (1248358)
  // can result in using an incompatible rwin and window
  // scale option on localhost pipes if not set before connect.

  PRFileDesc *listener = nullptr;
  PRFileDesc *writer = nullptr;
  PRFileDesc *reader = nullptr;
  PRSocketOptionData recvBufferOpt;
  recvBufferOpt.option = PR_SockOpt_RecvBufferSize;
  recvBufferOpt.value.recv_buffer_size = 65535;

  PRSocketOptionData nodelayOpt;
  nodelayOpt.option = PR_SockOpt_NoDelay;
  nodelayOpt.value.no_delay = true;

  PRSocketOptionData noblockOpt;
  noblockOpt.option = PR_SockOpt_Nonblocking;
  noblockOpt.value.non_blocking = true;

  listener = PR_OpenTCPSocket(PR_AF_INET);
  if (!listener) {
    goto failed;
  }
  PR_SetSocketOption(listener, &recvBufferOpt);
  PR_SetSocketOption(listener, &nodelayOpt);

  PRNetAddr listenAddr;
  memset(&listenAddr, 0, sizeof(listenAddr));
  if ((PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &listenAddr) == PR_FAILURE) ||
      (PR_Bind(listener, &listenAddr) == PR_FAILURE) ||
      (PR_GetSockName(listener, &listenAddr) == PR_FAILURE) || // learn the dynamic port
      (PR_Listen(listener, 5) == PR_FAILURE)) {
    goto failed;
  }

  writer = PR_OpenTCPSocket(PR_AF_INET);
  if (!writer) {
    goto failed;
  }
  PR_SetSocketOption(writer, &recvBufferOpt);
  PR_SetSocketOption(writer, &nodelayOpt);
  PR_SetSocketOption(writer, &noblockOpt);
  PRNetAddr writerAddr;
  if (PR_InitializeNetAddr(PR_IpAddrLoopback, ntohs(listenAddr.inet.port), &writerAddr) == PR_FAILURE) {
    goto failed;
  }

  if (PR_Connect(writer, &writerAddr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
    if ((PR_GetError() != PR_IN_PROGRESS_ERROR) ||
        (PR_ConnectContinue(writer, PR_POLL_WRITE) == PR_FAILURE)) {
      goto failed;
    }
  }

  reader = PR_Accept(listener, &listenAddr, PR_INTERVAL_NO_TIMEOUT);
  if (!reader) {
    goto failed;
  }
  PR_SetSocketOption(reader, &recvBufferOpt);
  PR_SetSocketOption(reader, &nodelayOpt);
  PR_SetSocketOption(reader, &noblockOpt);
  PR_Close(listener);

  fd[0] = reader;
  fd[1] = writer;
  return true;

failed:
  if (listener) {
    PR_Close(listener);
  }
  if (reader) {
    PR_Close(reader);
  }
  if (writer) {
    PR_Close(writer);
  }
  return false;
}
int main(int argc, char** argv)
{
    PRUintn index;
    PRBool boolean;
    CSClient_t *client;
    PRStatus rv, joinStatus;
    CSServer_t *server = NULL;

    PRUintn backlog = DEFAULT_BACKLOG;
    PRUintn clients = DEFAULT_CLIENTS;
    const char *serverName = DEFAULT_SERVER;
    PRBool serverIsLocal = PR_TRUE;
    PRUintn accepting = ALLOWED_IN_ACCEPT;
    PRUintn workersMin = DEFAULT_WORKERS_MIN;
    PRUintn workersMax = DEFAULT_WORKERS_MAX;
    PRIntn execution = DEFAULT_EXECUTION_TIME;
    PRIntn low = DEFAULT_LOW, high = DEFAULT_HIGH;

    /*
     * -G           use global threads
     * -a <n>       threads allowed in accept
     * -b <n>       backlock for listen
     * -c <threads> number of clients to create
     * -f <low>     low water mark for caching FDs
     * -F <high>    high water mark for caching FDs
     * -w <threads> minimal number of server threads
     * -W <threads> maximum number of server threads
     * -e <seconds> duration of the test in seconds
     * -s <string>  dsn name of server (implies no server here)
     * -v           verbosity
     */

    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "GX6b:a:c:f:F:w:W:e:s:vdhp");

    debug_out = PR_GetSpecialFD(PR_StandardError);

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'G':  /* use global threads */
            thread_scope = PR_GLOBAL_THREAD;
            break;
        case 'X':  /* use XTP as transport */
            protocol = 36;
            break;
        case '6':  /* Use IPv6 */
            domain = PR_AF_INET6;
            break;
        case 'a':  /* the value for accepting */
            accepting = atoi(opt->value);
            break;
        case 'b':  /* the value for backlock */
            backlog = atoi(opt->value);
            break;
        case 'c':  /* number of client threads */
            clients = atoi(opt->value);
            break;
        case 'f':  /* low water fd cache */
            low = atoi(opt->value);
            break;
        case 'F':  /* low water fd cache */
            high = atoi(opt->value);
            break;
        case 'w':  /* minimum server worker threads */
            workersMin = atoi(opt->value);
            break;
        case 'W':  /* maximum server worker threads */
            workersMax = atoi(opt->value);
            break;
        case 'e':  /* program execution time in seconds */
            execution = atoi(opt->value);
            break;
        case 's':  /* server's address */
            serverName = opt->value;
            break;
        case 'v':  /* verbosity */
            verbosity = IncrementVerbosity();
            break;
        case 'd':  /* debug mode */
            debug_mode = PR_TRUE;
            break;
        case 'p':  /* pthread mode */
            pthread_stats = PR_TRUE;
            break;
        case 'h':
        default:
            Help();
            return 2;
        }
    }
    PL_DestroyOptState(opt);

    if (0 != PL_strcmp(serverName, DEFAULT_SERVER)) serverIsLocal = PR_FALSE;
    if (0 == execution) execution = DEFAULT_EXECUTION_TIME;
    if (0 == workersMax) workersMax = DEFAULT_WORKERS_MAX;
    if (0 == workersMin) workersMin = DEFAULT_WORKERS_MIN;
    if (0 == accepting) accepting = ALLOWED_IN_ACCEPT;
    if (0 == backlog) backlog = DEFAULT_BACKLOG;

    if (workersMin > accepting) accepting = workersMin;

    PR_STDIO_INIT();
    TimeOfDayMessage("Client/Server started at", PR_GetCurrentThread());

    cltsrv_log_file = PR_NewLogModule("cltsrv_log");
    MY_ASSERT(NULL != cltsrv_log_file);
    boolean = PR_SetLogFile("cltsrv.log");
    MY_ASSERT(boolean);

    rv = PR_SetFDCacheSize(low, high);
    PR_ASSERT(PR_SUCCESS == rv);

    if (serverIsLocal)
    {
        /* Establish the server */
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_INFO,
            ("main(0x%p): starting server\n", PR_GetCurrentThread()));

        server = PR_NEWZAP(CSServer_t);
        PR_INIT_CLIST(&server->list);
        server->state = cs_init;
        server->ml = PR_NewLock();
        server->backlog = backlog;
        server->port = DEFAULT_PORT;
        server->workers.minimum = workersMin;
        server->workers.maximum = workersMax;
        server->workers.accepting = accepting;
        server->stateChange = PR_NewCondVar(server->ml);
        server->pool.exiting = PR_NewCondVar(server->ml);
        server->pool.acceptComplete = PR_NewCondVar(server->ml);

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE,
            ("main(0x%p): creating server thread\n", PR_GetCurrentThread()));

        server->thread = PR_CreateThread(
            PR_USER_THREAD, Server, server, PR_PRIORITY_HIGH,
            thread_scope, PR_JOINABLE_THREAD, 0);
        TEST_ASSERT(NULL != server->thread);

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("main(0x%p): waiting for server init\n", PR_GetCurrentThread()));

        PR_Lock(server->ml);
        while (server->state == cs_init)
            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
        PR_Unlock(server->ml);

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("main(0x%p): server init complete (port #%d)\n",
            PR_GetCurrentThread(), server->port));
    }

    if (clients != 0)
    {
        /* Create all of the clients */
        PRHostEnt host;
        char buffer[BUFFER_SIZE];
        client = (CSClient_t*)PR_CALLOC(clients * sizeof(CSClient_t));

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("main(0x%p): creating %d client threads\n",
            PR_GetCurrentThread(), clients));
        
        if (!serverIsLocal)
        {
            rv = PR_GetHostByName(serverName, buffer, BUFFER_SIZE, &host);
            if (PR_SUCCESS != rv)
            {
                PL_FPrintError(PR_STDERR, "PR_GetHostByName");
                return 2;
            }
        }

        for (index = 0; index < clients; ++index)
        {
            client[index].state = cs_init;
            client[index].ml = PR_NewLock();
            if (serverIsLocal)
            {
				if (PR_AF_INET6 != domain)
                	(void)PR_InitializeNetAddr(
                    	PR_IpAddrLoopback, DEFAULT_PORT,
                    	&client[index].serverAddress);
				else
					rv = PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6,
							DEFAULT_PORT, &client[index].serverAddress);
            }
            else
            {
                (void)PR_EnumerateHostEnt(
                    0, &host, DEFAULT_PORT, &client[index].serverAddress);
            }
            client[index].stateChange = PR_NewCondVar(client[index].ml);
            TEST_LOG(
                cltsrv_log_file, TEST_LOG_INFO,
                ("main(0x%p): creating client threads\n", PR_GetCurrentThread()));
            client[index].thread = PR_CreateThread(
                PR_USER_THREAD, Client, &client[index], PR_PRIORITY_NORMAL,
                thread_scope, PR_JOINABLE_THREAD, 0);
            TEST_ASSERT(NULL != client[index].thread);
            PR_Lock(client[index].ml);
            while (cs_init == client[index].state)
                PR_WaitCondVar(client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
            PR_Unlock(client[index].ml);
        }
    }

    /* Then just let them go at it for a bit */
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS,
        ("main(0x%p): waiting for execution interval (%d seconds)\n",
        PR_GetCurrentThread(), execution));

    WaitForCompletion(execution);

    TimeOfDayMessage("Shutting down", PR_GetCurrentThread());

    if (clients != 0)
    {
        for (index = 0; index < clients; ++index)
        {
            TEST_LOG(cltsrv_log_file, TEST_LOG_STATUS, 
                ("main(0x%p): notifying client(0x%p) to stop\n",
                PR_GetCurrentThread(), client[index].thread));

            PR_Lock(client[index].ml);
            if (cs_run == client[index].state)
            {
                client[index].state = cs_stop;
                PR_Interrupt(client[index].thread);
                while (cs_stop == client[index].state)
                    PR_WaitCondVar(
                        client[index].stateChange, PR_INTERVAL_NO_TIMEOUT);
            }
            PR_Unlock(client[index].ml);

            TEST_LOG(cltsrv_log_file, TEST_LOG_VERBOSE, 
                ("main(0x%p): joining client(0x%p)\n",
                PR_GetCurrentThread(), client[index].thread));

		    joinStatus = PR_JoinThread(client[index].thread);
		    TEST_ASSERT(PR_SUCCESS == joinStatus);
            PR_DestroyCondVar(client[index].stateChange);
            PR_DestroyLock(client[index].ml);
        }
        PR_DELETE(client);
    }

    if (NULL != server)
    {
        /* All clients joined - retrieve the server */
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE, 
            ("main(0x%p): notifying server(0x%p) to stop\n",
            PR_GetCurrentThread(), server->thread));

        PR_Lock(server->ml);
        server->state = cs_stop;
        PR_Interrupt(server->thread);
        while (cs_exit != server->state)
            PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
        PR_Unlock(server->ml);

        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE, 
            ("main(0x%p): joining server(0x%p)\n",
            PR_GetCurrentThread(), server->thread));
        joinStatus = PR_JoinThread(server->thread);
        TEST_ASSERT(PR_SUCCESS == joinStatus);

        PR_DestroyCondVar(server->stateChange);
        PR_DestroyCondVar(server->pool.exiting);
        PR_DestroyCondVar(server->pool.acceptComplete);
        PR_DestroyLock(server->ml);
        PR_DELETE(server);
    }

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS, 
        ("main(0x%p): test complete\n", PR_GetCurrentThread()));

    PT_FPrintStats(debug_out, "\nPThread Statistics\n");

    TimeOfDayMessage("Test exiting at", PR_GetCurrentThread());
    PR_Cleanup();
    return 0;
}  /* main */
Exemplo n.º 22
0
int
main(int argc, char* argv[])
{
    if (test_common_init(&argc, &argv) != 0)
        return -1;

    int returnCode = 0;
    nsresult rv = NS_OK;
    PRFileDesc *serverFD = nullptr;

    do { // act both as a scope for nsCOMPtrs to be released before XPCOM
        // shutdown, as well as a easy way to abort the test
        PRStatus status = PR_SUCCESS;

        nsCOMPtr<nsIServiceManager> servMan;
        NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr);
        nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
        UDP_ASSERT(registrar, "Null nsIComponentRegistrar");
        if (registrar)
            registrar->AutoRegister(nullptr);

        // listen for a incoming UDP connection on localhost
        serverFD = PR_OpenUDPSocket(PR_AF_INET);
        UDP_ASSERT(serverFD, "Cannot open UDP socket for listening");

        PRSocketOptionData socketOptions;
        socketOptions.option = PR_SockOpt_Nonblocking;
        socketOptions.value.non_blocking = false;
        status = PR_SetSocketOption(serverFD, &socketOptions);
        UDP_ASSERT_PRSTATUS("Failed to set server socket as blocking");

        PRNetAddr addr;
        status = PR_InitializeNetAddr(PR_IpAddrLoopback, UDP_PORT, &addr);
        UDP_ASSERT_PRSTATUS("Failed to initialize loopback address");

        status = PR_Bind(serverFD, &addr);
        UDP_ASSERT_PRSTATUS("Failed to bind server socket");

        // dummy IOService to get around bug 379890
        nsCOMPtr<nsISupports> ios =
            do_GetService("@mozilla.org/network/io-service;1");

        // and have a matching UDP connection for the client
        nsCOMPtr<nsISocketTransportService> sts =
            do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
        UDP_ASSERT_NSRESULT("Cannot get socket transport service");

        nsCOMPtr<nsISocketTransport> transport;
        const char *protocol = "udp";
        rv = sts->CreateTransport(&protocol, 1, NS_LITERAL_CSTRING("localhost"),
                                  UDP_PORT, nullptr, getter_AddRefs(transport));
        UDP_ASSERT_NSRESULT("Cannot create transport");

        uint32_t count, read;
        const uint32_t data = 0xFF0056A9;

        // write to the output stream
        nsCOMPtr<nsIOutputStream> outstream;
        rv = transport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
                                         0, 0, getter_AddRefs(outstream));
        UDP_ASSERT_NSRESULT("Cannot open output stream");

        rv = outstream->Write((const char*)&data, sizeof(uint32_t), &count);
        UDP_ASSERT_NSRESULT("Cannot write to output stream");
        UDP_ASSERT(count == sizeof(uint32_t),
                   "Did not write enough bytes to output stream");

        // read from NSPR to check it's the same
        count = PR_RecvFrom(serverFD, &read, sizeof(uint32_t), 0, &addr, 1);
        UDP_ASSERT(count == sizeof(uint32_t),
                   "Did not read enough bytes from NSPR");
        status = (read == data ? PR_SUCCESS : PR_FAILURE);
        UDP_ASSERT_PRSTATUS("Did not read expected data from NSPR");

        // write to NSPR
        count = PR_SendTo(serverFD, &data, sizeof(uint32_t), 0, &addr, 1);
        status = (count == sizeof(uint32_t) ? PR_SUCCESS : PR_FAILURE);
        UDP_ASSERT_PRSTATUS("Did not write enough bytes to NSPR");

        // read from stream
        nsCOMPtr<nsIInputStream> instream;
        rv = transport->OpenInputStream(nsITransport::OPEN_BLOCKING,
                                        0, 0, getter_AddRefs(instream));
        UDP_ASSERT_NSRESULT("Cannot open input stream");

        rv = instream->Read((char*)&read, sizeof(uint32_t), &count);
        UDP_ASSERT_NSRESULT("Cannot read from input stream");
        UDP_ASSERT(count == sizeof(uint32_t),
                   "Did not read enough bytes from input stream");
        UDP_ASSERT(read == data, "Did not read expected data from stream");

    } while (false); // release all XPCOM things
    if (serverFD) {
        PRStatus status = PR_Close(serverFD);
        if (status != PR_SUCCESS) {
            PRErrorCode err = PR_GetError();
            fprintf(stderr, "FAIL: Cannot close server: (%08x) %s\n",
                    err, PR_ErrorToString(err, PR_LANGUAGE_I_DEFAULT));
        }
    }
    rv = NS_ShutdownXPCOM(nullptr);
    NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");

    return returnCode;
}
Exemplo n.º 23
0
Arquivo: dns.cpp Projeto: leto/389-ds
char *dns_ip2host(char *ip, int verify)
{
    /*    struct in_addr iaddr;  */
    PRNetAddr iaddr;
    char *hn;
    static unsigned long laddr = 0;
    static char myhostname[256];
    PRHostEnt   hent;
    char        buf[PR_NETDB_BUF_SIZE];
    PRStatus    err;


    err = PR_InitializeNetAddr(PR_IpAddrNull, 0, &iaddr);

	/* richm: ipv6 cleanup - use inet_aton or other more appropriate function
	   instead of inet_addr */
    if((iaddr.inet.ip = inet_addr(ip)) == (in_addr_t)-1)
        goto bong;

    /*
     * See if it happens to be the localhost IP address, and try
     * the local host name if so.
     */
    if (laddr == 0) {
	laddr = inet_addr("127.0.0.1");
	myhostname[0] = 0;
	PR_GetSystemInfo(PR_SI_HOSTNAME, myhostname, sizeof(myhostname));
    }

    /* Have to match the localhost IP address and have a hostname */
    if ((iaddr.inet.ip == laddr) && (myhostname[0] != 0)) {
        /*
         * Now try for a fully-qualified domain name, starting with
         * the local hostname.
         */
        err =  PR_GetHostByName(myhostname,
				buf,
				PR_NETDB_BUF_SIZE,
				&hent);

        /* Don't verify if we get a fully-qualified name this way */
        verify = 0;
    }
    else {
      err = PR_GetHostByAddr(&iaddr, 
			     buf,
			     PR_NETDB_BUF_SIZE,
			     &hent);
    }

    if ((err == PR_FAILURE) || !(hn = net_find_fqdn(&hent))) goto bong;


    if(verify) {
        char **haddr = 0;
       	err = PR_GetHostByName(hn,
			       buf,
			       PR_NETDB_BUF_SIZE,
			       &hent);
 
        if(err == PR_SUCCESS) {
            for(haddr = hent.h_addr_list; *haddr; haddr++) {
                if(((struct in_addr *)(*haddr))->s_addr == iaddr.inet.ip)
                    break;
            }
        }

        if((err == PR_FAILURE) || (!(*haddr)))
            goto bong;
    }

    return hn;
  bong:
    return NULL;
}
Exemplo n.º 24
0
nsresult
UDPSocket::InitLocal(const nsAString& aLocalAddress,
                     const uint16_t& aLocalPort)
{
  nsresult rv;

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner(), &rv);
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCOMPtr<nsIPrincipal> principal = global->PrincipalOrNull();
  if (!principal) {
    return NS_ERROR_FAILURE;
  }

  if (aLocalAddress.IsEmpty()) {
    rv = sock->Init(aLocalPort, /* loopback = */ false, principal,
                    mAddressReuse, /* optionalArgc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr);
    PR_StringToNetAddr(NS_ConvertUTF16toUTF8(aLocalAddress).BeginReading(), &prAddr);
    UDPSOCKET_LOG(("%s: %s:%u", __FUNCTION__, NS_ConvertUTF16toUTF8(aLocalAddress).get(), aLocalPort));

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, principal, mAddressReuse,
                               /* optionalArgc = */ 1);
  }
  if (NS_FAILED(rv)) {
    return rv;
  }

  rv = sock->SetMulticastLoopback(mLoopback);
  if (NS_FAILED(rv)) {
    return rv;
  }

  mSocket = sock;

  // Get real local address and local port
  nsCOMPtr<nsINetAddr> localAddr;
  rv = mSocket->GetLocalAddr(getter_AddRefs(localAddr));
  if (NS_FAILED(rv)) {
    return rv;
  }

  nsCString localAddress;
  rv = localAddr->GetAddress(localAddress);
  if (NS_FAILED(rv)) {
    return rv;
  }
  mLocalAddress = NS_ConvertUTF8toUTF16(localAddress);

  uint16_t localPort;
  rv = localAddr->GetPort(&localPort);
  if (NS_FAILED(rv)) {
    return rv;
  }
  mLocalPort.SetValue(localPort);

  mListenerProxy = new ListenerProxy(this);

  rv = mSocket->AsyncListen(mListenerProxy);
  if (NS_FAILED(rv)) {
    return rv;
  }

  mReadyState = SocketReadyState::Open;
  rv = DoPendingMcastCommand();
  if (NS_FAILED(rv)) {
    return rv;
  }

  mOpened->MaybeResolve(JS::UndefinedHandleValue);

  return NS_OK;
}
Exemplo n.º 25
0
bool
TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost,
                              const uint16_t& aRemotePort,
                              const nsCString& aLocalAddr,
                              const uint16_t& aLocalPort,
                              const bool&     aUseSSL,
                              const bool&     aUseArrayBuffers,
                              const nsCString& aFilter)
{
  if (net::UsingNeckoIPCSecurity() &&
      !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsresult rv;
  nsCOMPtr<nsISocketTransportService> sts =
    do_GetService("@mozilla.org/network/socket-transport-service;1", &rv);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  nsCOMPtr<nsISocketTransport> socketTransport;
  rv = sts->CreateTransport(nullptr, 0,
                            aRemoteHost, aRemotePort,
                            nullptr, getter_AddRefs(socketTransport));
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  PRNetAddr prAddr;
  if (PR_SUCCESS != PR_InitializeNetAddr(PR_IpAddrAny, aLocalPort, &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }
  if (PR_SUCCESS != PR_StringToNetAddr(aLocalAddr.BeginReading(), &prAddr)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  mozilla::net::NetAddr addr;
  PRNetAddrToNetAddr(&prAddr, &addr);
  rv = socketTransport->Bind(&addr);
  if (NS_FAILED(rv)) {
    FireInteralError(this, __LINE__);
    return true;
  }

  if (!aFilter.IsEmpty()) {
    nsAutoCString contractId(NS_NETWORK_TCP_SOCKET_FILTER_HANDLER_PREFIX);
    contractId.Append(aFilter);
    nsCOMPtr<nsISocketFilterHandler> filterHandler =
      do_GetService(contractId.get());
    if (!filterHandler) {
      NS_ERROR("Content doesn't have a valid filter");
      FireInteralError(this, __LINE__);
      return true;
    }
    rv = filterHandler->NewFilter(getter_AddRefs(mFilter));
    if (NS_FAILED(rv)) {
      NS_ERROR("Cannot create filter that content specified");
      FireInteralError(this, __LINE__);
      return true;
    }
  }

  // Obtain App ID
  uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
  bool     inIsolatedMozBrowser = false;
  const PContentParent *content = Manager()->Manager();
  if (PBrowserParent* browser = SingleManagedOrNull(content->ManagedPBrowserParent())) {
    // appId's are for B2G only currently, where managees.Count() == 1
    // This is not guaranteed currently in Desktop, so skip this there.
    TabParent *tab = TabParent::GetFrom(browser);
    appId = tab->OwnAppId();
    inIsolatedMozBrowser = tab->IsIsolatedMozBrowserElement();
  }

  mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers);
  mSocket->SetAppIdAndBrowser(appId, inIsolatedMozBrowser);
  mSocket->SetSocketBridgeParent(this);
  rv = mSocket->InitWithUnconnectedTransport(socketTransport);
  NS_ENSURE_SUCCESS(rv, true);
  return true;
}
PR_IMPLEMENT(PRStatus) PR_NewTCPSocketPair(PRFileDesc *f[])
{
#ifdef XP_UNIX
	PRInt32 rv, osfd[2];

	if (!_pr_initialized) _PR_ImplicitInitialization();

	rv = _PR_MD_SOCKETPAIR(AF_UNIX, SOCK_STREAM, 0, osfd);
	if (rv == -1) {
		return PR_FAILURE;
	}

	f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
	if (!f[0]) {
		_PR_MD_CLOSE_SOCKET(osfd[0]);
		_PR_MD_CLOSE_SOCKET(osfd[1]);
		/* PR_AllocFileDesc() has invoked PR_SetError(). */
		return PR_FAILURE;
	}
	f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
	if (!f[1]) {
		PR_Close(f[0]);
		_PR_MD_CLOSE_SOCKET(osfd[1]);
		/* PR_AllocFileDesc() has invoked PR_SetError(). */
		return PR_FAILURE;
	}
	_PR_MD_MAKE_NONBLOCK(f[0]);
	_PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
	_PR_MD_MAKE_NONBLOCK(f[1]);
	_PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
	return PR_SUCCESS;
#elif defined(WINNT)
    /*
     * A socket pair is often used for interprocess communication,
     * so we need to make sure neither socket is associated with
     * the I/O completion port; otherwise it can't be used by a
     * child process.
     *
     * The default implementation below cannot be used for NT
     * because PR_Accept would have associated the I/O completion
     * port with the listening and accepted sockets.
     */
    SOCKET listenSock;
    SOCKET osfd[2];
    struct sockaddr_in selfAddr, peerAddr;
    int addrLen;

    if (!_pr_initialized) _PR_ImplicitInitialization();

    osfd[0] = osfd[1] = INVALID_SOCKET;
    listenSock = socket(AF_INET, SOCK_STREAM, 0);
    if (listenSock == INVALID_SOCKET) {
        goto failed;
    }
    selfAddr.sin_family = AF_INET;
    selfAddr.sin_port = 0;
    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* BugZilla: 35408 */
    addrLen = sizeof(selfAddr);
    if (bind(listenSock, (struct sockaddr *) &selfAddr,
            addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    if (getsockname(listenSock, (struct sockaddr *) &selfAddr,
            &addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    if (listen(listenSock, 5) == SOCKET_ERROR) {
        goto failed;
    }
    osfd[0] = socket(AF_INET, SOCK_STREAM, 0);
    if (osfd[0] == INVALID_SOCKET) {
        goto failed;
    }
    selfAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    /*
     * Only a thread is used to do the connect and accept.
     * I am relying on the fact that connect returns
     * successfully as soon as the connect request is put
     * into the listen queue (but before accept is called).
     * This is the behavior of the BSD socket code.  If
     * connect does not return until accept is called, we
     * will need to create another thread to call connect.
     */
    if (connect(osfd[0], (struct sockaddr *) &selfAddr,
            addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    /*
     * A malicious local process may connect to the listening
     * socket, so we need to verify that the accepted connection
     * is made from our own socket osfd[0].
     */
    if (getsockname(osfd[0], (struct sockaddr *) &selfAddr,
            &addrLen) == SOCKET_ERROR) {
        goto failed;
    }
    osfd[1] = accept(listenSock, (struct sockaddr *) &peerAddr, &addrLen);
    if (osfd[1] == INVALID_SOCKET) {
        goto failed;
    }
    if (peerAddr.sin_port != selfAddr.sin_port) {
        /* the connection we accepted is not from osfd[0] */
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
        goto failed;
    }
    closesocket(listenSock);

    f[0] = PR_AllocFileDesc(osfd[0], PR_GetTCPMethods());
    if (!f[0]) {
        closesocket(osfd[0]);
        closesocket(osfd[1]);
        /* PR_AllocFileDesc() has invoked PR_SetError(). */
        return PR_FAILURE;
    }
    f[1] = PR_AllocFileDesc(osfd[1], PR_GetTCPMethods());
    if (!f[1]) {
        PR_Close(f[0]);
        closesocket(osfd[1]);
        /* PR_AllocFileDesc() has invoked PR_SetError(). */
        return PR_FAILURE;
    }
    _PR_MD_INIT_FD_INHERITABLE(f[0], PR_FALSE);
    _PR_MD_INIT_FD_INHERITABLE(f[1], PR_FALSE);
    return PR_SUCCESS;

failed:
    if (listenSock != INVALID_SOCKET) {
        closesocket(listenSock);
    }
    if (osfd[0] != INVALID_SOCKET) {
        closesocket(osfd[0]);
    }
    if (osfd[1] != INVALID_SOCKET) {
        closesocket(osfd[1]);
    }
    return PR_FAILURE;
#else /* not Unix or NT */
    /*
     * default implementation
     */
    PRFileDesc *listenSock;
    PRNetAddr selfAddr, peerAddr;
    PRUint16 port;

    f[0] = f[1] = NULL;
    listenSock = PR_NewTCPSocket();
    if (listenSock == NULL) {
        goto failed;
    }
    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr); /* BugZilla: 35408 */
    if (PR_Bind(listenSock, &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    if (PR_GetSockName(listenSock, &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    port = ntohs(selfAddr.inet.port);
    if (PR_Listen(listenSock, 5) == PR_FAILURE) {
        goto failed;
    }
    f[0] = PR_NewTCPSocket();
    if (f[0] == NULL) {
        goto failed;
    }
#ifdef _PR_CONNECT_DOES_NOT_BIND
    /*
     * If connect does not implicitly bind the socket (e.g., on
     * BeOS), we have to bind the socket so that we can get its
     * port with getsockname later.
     */
    PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &selfAddr);
    if (PR_Bind(f[0], &selfAddr) == PR_FAILURE) {
        goto failed;
    }
#endif
    PR_InitializeNetAddr(PR_IpAddrLoopback, port, &selfAddr);

    /*
     * Only a thread is used to do the connect and accept.
     * I am relying on the fact that PR_Connect returns
     * successfully as soon as the connect request is put
     * into the listen queue (but before PR_Accept is called).
     * This is the behavior of the BSD socket code.  If
     * connect does not return until accept is called, we
     * will need to create another thread to call connect.
     */
    if (PR_Connect(f[0], &selfAddr, PR_INTERVAL_NO_TIMEOUT)
            == PR_FAILURE) {
        goto failed;
    }
    /*
     * A malicious local process may connect to the listening
     * socket, so we need to verify that the accepted connection
     * is made from our own socket f[0].
     */
    if (PR_GetSockName(f[0], &selfAddr) == PR_FAILURE) {
        goto failed;
    }
    f[1] = PR_Accept(listenSock, &peerAddr, PR_INTERVAL_NO_TIMEOUT);
    if (f[1] == NULL) {
        goto failed;
    }
    if (peerAddr.inet.port != selfAddr.inet.port) {
        /* the connection we accepted is not from f[0] */
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
        goto failed;
    }
    PR_Close(listenSock);
    return PR_SUCCESS;

failed:
    if (listenSock) {
        PR_Close(listenSock);
    }
    if (f[0]) {
        PR_Close(f[0]);
    }
    if (f[1]) {
        PR_Close(f[1]);
    }
    return PR_FAILURE;
#endif
}
Exemplo n.º 27
0
int main(int argc, char **argv)
#endif
{
    const char *hostName = DEFAULT_HOST_NAME;
    PRHostEnt he, reversehe;
    char buf[PR_NETDB_BUF_SIZE];
    char reversebuf[PR_NETDB_BUF_SIZE];
    PRIntn idx;
    PRNetAddr addr;
    PLOptStatus os;
    PLOptState *opt = PL_CreateOptState(argc, argv, "h");

    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
        if (PL_OPT_BAD == os) continue;
        switch (opt->option) {
            case 0:  /* naked */
                hostName = opt->value;
                break;
            case 'h':  /* Help message */
            default:
                Help();
                return 2;
        }
    }
    PL_DestroyOptState(opt);

    PR_STDIO_INIT();
    outFile = PR_GetSpecialFD(PR_StandardError);

    if (PR_GetHostByName(hostName, buf, sizeof(buf), &he) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_GetHostByName failed\n");
        exit(1);
    }
    PrintHostent(&he);
    idx = 0;

    while (1) {
        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
        if (idx == -1) {
            PR_fprintf(outFile, "PR_EnumerateHostEnt failed\n");
            exit(1);
        }
        if (idx == 0) break;  /* normal loop termination */
        PR_fprintf(outFile, "reverse lookup\n");
        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
                &reversehe) == PR_FAILURE) {
            PR_fprintf(outFile, "PR_GetHostByAddr failed\n");
            exit(1);
        }
        PrintHostent(&reversehe);
    }

    PR_fprintf(outFile, "PR_GetIPNodeByName with PR_AF_INET\n");
    if (PR_GetIPNodeByName(hostName, PR_AF_INET, PR_AI_DEFAULT,
            buf, sizeof(buf), &he) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_GetIPNodeByName failed\n");
        exit(1);
    }
    PrintHostent(&he);
    PR_fprintf(outFile, "PR_GetIPNodeByName with PR_AF_INET6\n");
    if (PR_GetIPNodeByName(hostName, PR_AF_INET6, PR_AI_DEFAULT,
            buf, sizeof(buf), &he) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_GetIPNodeByName failed\n");
        exit(1);
    }
    PrintHostent(&he);
    idx = 0;
    PR_fprintf(outFile, "PR_GetHostByAddr with PR_AF_INET6\n");
    while (1) {
        idx = PR_EnumerateHostEnt(idx, &he, 0, &addr);
        if (idx == -1) {
            PR_fprintf(outFile, "PR_EnumerateHostEnt failed\n");
            exit(1);
        }
        if (idx == 0) break;  /* normal loop termination */
        PR_fprintf(outFile, "reverse lookup\n");
        if (PR_GetHostByAddr(&addr, reversebuf, sizeof(reversebuf),
                &reversehe) == PR_FAILURE) {
            PR_fprintf(outFile, "PR_GetHostByAddr failed\n");
            exit(1);
        }
        PrintHostent(&reversehe);
    }
    PR_fprintf(outFile, "PR_GetHostByAddr with PR_AF_INET6 done\n");
  
    PR_StringToNetAddr("::1", &addr);
    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_TRUE) {
        PR_fprintf(outFile, "addr should not be ipv4 mapped address\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }

    PR_StringToNetAddr("127.0.0.1", &addr);
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }
    PR_StringToNetAddr("::FFFF:127.0.0.1", &addr);
    if (PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be ipv4 mapped address\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }

    if (PR_InitializeNetAddr(PR_IpAddrAny, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be unspecified address\n");
        exit(1);
    }
    if (PR_InitializeNetAddr(PR_IpAddrLoopback, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_InitializeNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }

    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_SetNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be unspecified address\n");
        exit(1);
    }
    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_SetNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }

    addr.inet.family = PR_AF_INET;
    addr.inet.port = 0;
    addr.inet.ip = PR_htonl(PR_INADDR_ANY);
    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be unspecified address\n");
        exit(1);
    }
	{
		char buf[256];
		PR_NetAddrToString(&addr, buf, 256);
		PR_fprintf(outFile, "IPv4 INADDRANY: %s\n", buf);
	}
    addr.inet.family = PR_AF_INET;
    addr.inet.port = 0;
    addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }
	{
		char buf[256];
		PR_NetAddrToString(&addr, buf, 256);
		PR_fprintf(outFile, "IPv4 LOOPBACK: %s\n", buf);
	}

    if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_SetNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrAny) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be unspecified address\n");
        exit(1);
    }
	{
		char buf[256];
		PR_NetAddrToString(&addr, buf, 256);
		PR_fprintf(outFile, "IPv6 INADDRANY: %s\n", buf);
	}
    if (PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
        PR_fprintf(outFile, "PR_SetNetAddr failed\n");
        exit(1);
    }
    if (PR_IsNetAddrType(&addr, PR_IpAddrLoopback) == PR_FALSE) {
        PR_fprintf(outFile, "addr should be loopback address\n");
        exit(1);
    }
	{
		char buf[256];
		PR_NetAddrToString(&addr, buf, 256);
		PR_fprintf(outFile, "IPv6 LOOPBACK: %s\n", buf);
	}
	{
		PRIPv6Addr v6addr;
		char tmp_buf[256];

    	PR_SetNetAddr(PR_IpAddrLoopback, PR_AF_INET, 0, &addr);

		PR_ConvertIPv4AddrToIPv6(addr.inet.ip, &v6addr);
    	PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr);
		addr.ipv6.ip = v6addr;
		PR_NetAddrToString(&addr, tmp_buf, 256);
		PR_fprintf(outFile, "IPv4-mapped IPv6 LOOPBACK: %s\n", tmp_buf);
	}
    PR_fprintf(outFile, "PASS\n");
    return 0;
}
Exemplo n.º 28
0
nsresult
UDPSocketParent::BindInternal(const nsCString& aHost, const uint16_t& aPort,
                              const bool& aAddressReuse, const bool& aLoopback,
                              const uint32_t& recvBufferSize,
                              const uint32_t& sendBufferSize)
{
  nsresult rv;

  UDPSOCKET_LOG(("%s: [this=%p] %s:%u addressReuse: %d loopback: %d recvBufferSize: %lu, sendBufferSize: %lu",
                __FUNCTION__, this, nsCString(aHost).get(), aPort,
                aAddressReuse, aLoopback, recvBufferSize, sendBufferSize));

  nsCOMPtr<nsIUDPSocket> sock =
      do_CreateInstance("@mozilla.org/network/udp-socket;1", &rv);

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  if (aHost.IsEmpty()) {
    rv = sock->Init(aPort, false, mPrincipal, aAddressReuse,
                    /* optional_argc = */ 1);
  } else {
    PRNetAddr prAddr;
    PR_InitializeNetAddr(PR_IpAddrAny, aPort, &prAddr);
    PRStatus status = PR_StringToNetAddr(aHost.BeginReading(), &prAddr);
    if (status != PR_SUCCESS) {
      return NS_ERROR_FAILURE;
    }

    mozilla::net::NetAddr addr;
    PRNetAddrToNetAddr(&prAddr, &addr);
    rv = sock->InitWithAddress(&addr, mPrincipal, aAddressReuse,
                               /* optional_argc = */ 1);
  }

  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  nsCOMPtr<nsINetAddr> laddr;
  rv = sock->GetLocalAddr(getter_AddRefs(laddr));
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  uint16_t family;
  rv = laddr->GetFamily(&family);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }
  if (family == nsINetAddr::FAMILY_INET) {
    rv = sock->SetMulticastLoopback(aLoopback);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      return rv;
    }
  }
  // TODO: once bug 1252759 is fixed query buffer first and only increase
  if (recvBufferSize != 0) {
    rv = sock->SetRecvBufferSize(recvBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set recv buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, recvBufferSize));
    }
  }
  if (sendBufferSize != 0) {
    rv = sock->SetSendBufferSize(sendBufferSize);
    if (NS_WARN_IF(NS_FAILED(rv))) {
      UDPSOCKET_LOG(("%s: [this=%p] %s:%u failed to set send buffer size to: %lu", __FUNCTION__, this, nsCString(aHost).get(), aPort, sendBufferSize));
    }
  }

  // register listener
  rv = sock->AsyncListen(this);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return rv;
  }

  mSocket = sock;

  return NS_OK;
}
static void PR_CALLBACK Server(void *arg)
{
    PRStatus rv;
    PRNetAddr serverAddress;
    PRThread *me = PR_GetCurrentThread();
    CSServer_t *server = (CSServer_t*)arg;
    PRSocketOptionData sockOpt;

    server->listener = PR_Socket(domain, SOCK_STREAM, protocol);

    sockOpt.option = PR_SockOpt_Reuseaddr;
    sockOpt.value.reuse_addr = PR_TRUE;
    rv = PR_SetSocketOption(server->listener, &sockOpt);
    TEST_ASSERT(PR_SUCCESS == rv);

    memset(&serverAddress, 0, sizeof(serverAddress));
	if (PR_AF_INET6 != domain)
		rv = PR_InitializeNetAddr(PR_IpAddrAny, DEFAULT_PORT, &serverAddress);
	else
		rv = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, DEFAULT_PORT,
													&serverAddress);
    rv = PR_Bind(server->listener, &serverAddress);
    TEST_ASSERT(PR_SUCCESS == rv);

    rv = PR_Listen(server->listener, server->backlog);
    TEST_ASSERT(PR_SUCCESS == rv);

    server->started = PR_IntervalNow();
    TimeOfDayMessage("Server started at", me);

    PR_Lock(server->ml);
    server->state = cs_run;
    PR_NotifyCondVar(server->stateChange);
    PR_Unlock(server->ml);

    /*
    ** Create the first worker (actually, a thread that accepts
    ** connections and then processes the work load as needed).
    ** From this point on, additional worker threads are created
    ** as they are needed by existing worker threads.
    */
    rv = CreateWorker(server, &server->pool);
    TEST_ASSERT(PR_SUCCESS == rv);

    /*
    ** From here on this thread is merely hanging around as the contact
    ** point for the main test driver. It's just waiting for the driver
    ** to declare the test complete.
    */
    TEST_LOG(
        cltsrv_log_file, TEST_LOG_VERBOSE,
        ("\tServer(0x%p): waiting for state change\n", me));

    PR_Lock(server->ml);
    while ((cs_run == server->state) && !Aborted(rv))
    {
        rv = PR_WaitCondVar(server->stateChange, PR_INTERVAL_NO_TIMEOUT);
    }
    PR_Unlock(server->ml);
    PR_ClearInterrupt();

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_INFO,
        ("\tServer(0x%p): shutting down workers\n", me));

    /*
    ** Get all the worker threads to exit. They know how to
    ** clean up after themselves, so this is just a matter of
    ** waiting for clorine in the pool to take effect. During
    ** this stage we're ignoring interrupts.
    */
    server->workers.minimum = server->workers.maximum = 0;

    PR_Lock(server->ml);
    while (!PR_CLIST_IS_EMPTY(&server->list))
    {
        PRCList *head = PR_LIST_HEAD(&server->list);
        CSWorker_t *worker = (CSWorker_t*)head;
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_VERBOSE,
            ("\tServer(0x%p): interrupting worker(0x%p)\n", me, worker));
        rv = PR_Interrupt(worker->thread);
        TEST_ASSERT(PR_SUCCESS == rv);
        PR_REMOVE_AND_INIT_LINK(head);
    }

    while (server->pool.workers > 0)
    {
        TEST_LOG(
            cltsrv_log_file, TEST_LOG_NOTICE,
            ("\tServer(0x%p): waiting for %u workers to exit\n",
            me, server->pool.workers));
        (void)PR_WaitCondVar(server->pool.exiting, PR_INTERVAL_NO_TIMEOUT);
    }

    server->state = cs_exit;
    PR_NotifyCondVar(server->stateChange);
    PR_Unlock(server->ml);

    TEST_LOG(
        cltsrv_log_file, TEST_LOG_ALWAYS,
        ("\tServer(0x%p): stopped after %u operations and %u bytes\n",
        me, server->operations, server->bytesTransferred));

    if (NULL != server->listener) PR_Close(server->listener);
    server->stopped = PR_IntervalNow();

}  /* Server */
Exemplo n.º 30
0
int
StartServer(const char *nssCertDBDir, SSLSNISocketConfig sniSocketConfig,
            void *sniSocketConfigArg)
{
  const char *debugLevel = PR_GetEnv("MOZ_TLS_SERVER_DEBUG_LEVEL");
  if (debugLevel) {
    int level = atoi(debugLevel);
    switch (level) {
      case DEBUG_ERRORS: gDebugLevel = DEBUG_ERRORS; break;
      case DEBUG_WARNINGS: gDebugLevel = DEBUG_WARNINGS; break;
      case DEBUG_VERBOSE: gDebugLevel = DEBUG_VERBOSE; break;
      default:
        PrintPRError("invalid MOZ_TLS_SERVER_DEBUG_LEVEL");
        return 1;
    }
  }

  const char *callbackPort = PR_GetEnv("MOZ_TLS_SERVER_CALLBACK_PORT");
  if (callbackPort) {
    gCallbackPort = atoi(callbackPort);
  }

  if (InitializeNSS(nssCertDBDir) != SECSuccess) {
    PR_fprintf(PR_STDERR, "InitializeNSS failed");
    return 1;
  }

  if (NSS_SetDomesticPolicy() != SECSuccess) {
    PrintPRError("NSS_SetDomesticPolicy failed");
    return 1;
  }

  if (SSL_ConfigServerSessionIDCache(0, 0, 0, nullptr) != SECSuccess) {
    PrintPRError("SSL_ConfigServerSessionIDCache failed");
    return 1;
  }

  UniquePRFileDesc serverSocket(PR_NewTCPSocket());
  if (!serverSocket) {
    PrintPRError("PR_NewTCPSocket failed");
    return 1;
  }

  PRSocketOptionData socketOption;
  socketOption.option = PR_SockOpt_Reuseaddr;
  socketOption.value.reuse_addr = true;
  PR_SetSocketOption(serverSocket.get(), &socketOption);

  PRNetAddr serverAddr;
  PR_InitializeNetAddr(PR_IpAddrLoopback, LISTEN_PORT, &serverAddr);
  if (PR_Bind(serverSocket.get(), &serverAddr) != PR_SUCCESS) {
    PrintPRError("PR_Bind failed");
    return 1;
  }

  if (PR_Listen(serverSocket.get(), 1) != PR_SUCCESS) {
    PrintPRError("PR_Listen failed");
    return 1;
  }

  UniquePRFileDesc rawModelSocket(PR_NewTCPSocket());
  if (!rawModelSocket) {
    PrintPRError("PR_NewTCPSocket failed for rawModelSocket");
    return 1;
  }

  UniquePRFileDesc modelSocket(SSL_ImportFD(nullptr, rawModelSocket.release()));
  if (!modelSocket) {
    PrintPRError("SSL_ImportFD of rawModelSocket failed");
    return 1;
  }

  if (SSL_SNISocketConfigHook(modelSocket.get(), sniSocketConfig,
                              sniSocketConfigArg) != SECSuccess) {
    PrintPRError("SSL_SNISocketConfigHook failed");
    return 1;
  }

  // We have to configure the server with a certificate, but it's not one
  // we're actually going to end up using. In the SNI callback, we pick
  // the right certificate for the connection.
  if (ConfigSecureServerWithNamedCert(modelSocket.get(), DEFAULT_CERT_NICKNAME,
                                      nullptr, nullptr) != SECSuccess) {
    return 1;
  }

  if (gCallbackPort != 0) {
    if (DoCallback()) {
      return 1;
    }
  }

  while (true) {
    PRNetAddr clientAddr;
    PRFileDesc* clientSocket = PR_Accept(serverSocket.get(), &clientAddr,
                                         PR_INTERVAL_NO_TIMEOUT);
    HandleConnection(clientSocket, modelSocket);
  }

  return 0;
}