Exemplo n.º 1
0
int
SocketBase::FCntl(int iCommand, long lArgument)
{
    int     iResult;

    WaitMutex();

    if ((iResult = fcntl(iSockDesc, iCommand, lArgument)) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EINTR:         throw SocketException(SocketException::errInterrupted);
            case EACCES:
            case EAGAIN:        throw SocketException(SocketException::errPermissionDenied);
            case EBADF:         throw SocketException(SocketException::errBadDescriptor);
            case EDEADLK:       throw SocketException(SocketException::errWouldBlock);
            case EFAULT:
            case EINVAL:
            case EPERM:         throw SocketException(SocketException::errInvalidArgument);
            case EMFILE:
            case ENOLCK:        throw SocketException(SocketException::errNoDescriptors);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    return iResult;
}
Exemplo n.º 2
0
void
SocketBase::GetPeerName(IPAddress &cRemoteAddr, int &iRemotePort)
{
    SocketAddress   cRemote;
    socklen_t       slDummy = cRemote.SizeOf();

    WaitMutex();

    if (getpeername(iSockDesc, (sockaddr *)cRemote, &slDummy) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:  throw SocketException(SocketException::errBadDescriptor);
            case ENOBUFS:   throw SocketException(SocketException::errKernelMemory);
            case EFAULT:    throw SocketException(SocketException::errIllegalPointer);
            default:        throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    cRemote.GetIPAddress(cRemoteAddr);
    cRemote.GetPortNumber(iRemotePort);
}
Exemplo n.º 3
0
int
SocketBase::Send(const void *pPayload, int iPayloadLength, unsigned int uiFlags)
{
    int             iBytesRead;

    WaitMutex();

    if ((iBytesRead = send(iSockDesc, pPayload, iPayloadLength, uiFlags)) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case EAGAIN:        throw SocketException(SocketException::errWouldBlock);
            case EINTR:         throw SocketException(SocketException::errInterrupted);
            case EFAULT:        throw SocketException(SocketException::errIllegalPointer);
            case EINVAL:        throw SocketException(SocketException::errInvalidArgument);
            case EMSGSIZE:      throw SocketException(SocketException::errMessageSizeTooBig);
            case ENOBUFS:
            case ENOMEM:        throw SocketException(SocketException::errKernelMemory);
            case ECONNREFUSED:
            case EPIPE:         throw SocketException(SocketException::errNotConnected);
            case EHOSTUNREACH:  throw SocketException(SocketException::errHostUnreachable);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    return iBytesRead;
}
Exemplo n.º 4
0
int
SocketBase::SendTo(const void *pPayload, int iPayloadLength, unsigned int uiFlags,
                   IPAddress &cDestinationIP, int iDestinationPortNumber)
{
    SocketAddress   cDestination;
    int             iBytesRead;

    cDestination.SetIPAddress(cDestinationIP);
    cDestination.SetPortNumber(iDestinationPortNumber);

    WaitMutex();

    if ((iBytesRead = sendto(iSockDesc, pPayload, iPayloadLength, uiFlags, (sockaddr *)cDestination, cDestination.SizeOf())) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:     throw SocketException(SocketException::errBadDescriptor);
            case EAGAIN:       throw SocketException(SocketException::errWouldBlock);
            case EINTR:        throw SocketException(SocketException::errInterrupted);
            case EFAULT:       throw SocketException(SocketException::errIllegalPointer);
            case EINVAL:       throw SocketException(SocketException::errInvalidArgument);
            case EMSGSIZE:     throw SocketException(SocketException::errMessageSizeTooBig);
            case ENOBUFS:
            case ENOMEM:       throw SocketException(SocketException::errKernelMemory);
            case EHOSTUNREACH: throw SocketException(SocketException::errHostUnreachable);
            case EPIPE:        throw SocketException(SocketException::errNotConnected);
            default:           throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    return iBytesRead;
}
Exemplo n.º 5
0
int
SocketBase::Recv(void *pBuffer, int iBufLength, unsigned int uiFlags)
{
    int     iBytesRead;

    WaitMutex();

    if ((iBytesRead = recvfrom(iSockDesc, pBuffer, iBufLength, uiFlags, NULL, NULL)) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case ECONNREFUSED:
            case ENOTCONN:      throw SocketException(SocketException::errNotConnected);
            case EAGAIN:        throw SocketException(SocketException::errWouldBlock);
            case EINTR:         throw SocketException(SocketException::errInterrupted);
            case EFAULT:        throw SocketException(SocketException::errIllegalPointer);
            case EINVAL:        throw SocketException(SocketException::errInvalidArgument);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    if (iBytesRead) return iBytesRead;
    throw SocketException(SocketException::errNotConnected);
}
Exemplo n.º 6
0
int
SocketBase::RecvFrom(void *pBuffer, int iBufLength, unsigned int uiFlags,
                     IPAddress &cSourceIP, int &iSourcePortNumber)
{
    SocketAddress   cSource;
    socklen_t       slDummy = cSource.SizeOf();
    int             iBytesRead;

    WaitMutex();

    if ((iBytesRead = recvfrom(iSockDesc, pBuffer, iBufLength, uiFlags, (sockaddr *)cSource, &slDummy)) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:  throw SocketException(SocketException::errBadDescriptor);
            case ENOTCONN:  throw SocketException(SocketException::errNotConnected);
            case EAGAIN:    throw SocketException(SocketException::errWouldBlock);
            case EINTR:     throw SocketException(SocketException::errInterrupted);
            case EFAULT:    throw SocketException(SocketException::errIllegalPointer);
            case EINVAL:    throw SocketException(SocketException::errInvalidArgument);
            default:        throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    if (iBytesRead)
    {
        cSource.GetIPAddress(cSourceIP);
        cSource.GetPortNumber(iSourcePortNumber);
        return iBytesRead;
    }
    throw SocketException(SocketException::errNotConnected);
}
Exemplo n.º 7
0
void
SocketBase::Connect(IPAddress &cServAddr, int iServPortNo)
{
    SocketAddress cServer;

    cServer.SetIPAddress(cServAddr);
    cServer.SetPortNumber(iServPortNo);

    WaitMutex();

    if (connect(iSockDesc, (sockaddr *) cServer, cServer.SizeOf()) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case EFAULT:        throw SocketException(SocketException::errIllegalPointer);
            case EISCONN:       throw SocketException(SocketException::errAlreadyConnected);
            case ECONNREFUSED:  throw SocketException(SocketException::errConnectRefused);
            case ETIMEDOUT:     throw SocketException(SocketException::errConnectTimeOut);
            case ENETUNREACH:   throw SocketException(SocketException::errNetUnreachable);
            case EHOSTUNREACH:  throw SocketException(SocketException::errHostUnreachable);
            case EADDRINUSE:    throw SocketException(SocketException::errAddrInUse);
            case EINPROGRESS:   throw SocketException(SocketException::errInProgress);
            case EALREADY:      throw SocketException(SocketException::errAlreadyConnecting);
            case EAFNOSUPPORT:  throw SocketException(SocketException::errIncorrectAddrFamily);
            case EACCES:        throw SocketException(SocketException::errBrdCastNotEnabled);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();
}
Exemplo n.º 8
0
int
SocketBase::protAccept(IPAddress &cRemoteAddr, int &iRemotePortNo)
{
    int           iNewSockDesc;
    SocketAddress cRemote;
    socklen_t     slDummy = cRemote.SizeOf();

    WaitMutex();

    if ((iNewSockDesc = accept(iSockDesc, (sockaddr *) cRemote, &slDummy)) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case EAFNOSUPPORT:  throw SocketException(SocketException::errNotStreamSock);
            case EFAULT:        throw SocketException(SocketException::errIllegalPointer);
            case EAGAIN:        throw SocketException(SocketException::errNoPendingConnections);
            case EPERM:         throw SocketException(SocketException::errFirewall);
            case ENOMEM:        throw SocketException(SocketException::errMemory);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();

    cRemote.GetIPAddress(cRemoteAddr);
    cRemote.GetPortNumber(iRemotePortNo);

    return iNewSockDesc;
}
Exemplo n.º 9
0
void
SocketBase::Bind(int iLocalPort)
{
    SocketAddress cLocal;

    cLocal.SetIPAddressWildCard(bIPv6Socket);
    cLocal.SetPortNumber(iLocalPort);

    WaitMutex();

    if (bind(iSockDesc, (sockaddr *)cLocal, cLocal.SizeOf()) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case EINVAL:        throw SocketException(SocketException::errAlreadyBound);
            case EACCES:        throw SocketException(SocketException::errAddressProtected);
            case EADDRINUSE:    throw SocketException(SocketException::errAddrInUse);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();
}
Exemplo n.º 10
0
int OutputTarget::DeactivateMcastAll (void)
{
	WaitMutex ();
	msg_type = 3;
	something_to_send.Post();
	PostMutex ();

	/// I may actually join here!
	YARPScheduler::yield();
	
	return YARP_OK;
}
Exemplo n.º 11
0
bool BtcRpcCurl::ConnectToBitcoin(BitcoinServerPtr server)
{
    WaitMutex();

    if(server == NULL)
    {
        this->currentServer = server;
        CleanUpCurl();
        mutex = false;
        return false;
    }

    if(this->currentServer != server || !this->curl || this->res != CURLE_OK)
    {
        this->currentServer = server;
        CleanUpCurl();

        /* In windows, this will init the winsock stuff */
        this->res = curl_global_init(CURL_GLOBAL_DEFAULT);

        /* Check for errors */
        if(res != CURLE_OK)
        {
          fprintf(stderr, "curl_global_init() failed: %s\n",
                  curl_easy_strerror(res));
          mutex = false;
          return false;
        }

        /* get a curl handle */
        curl = curl_easy_init();

        if(!curl)
        {
            mutex = false;
            return false;
        }
    }

    /* First set the URL that is about to receive our POST. */
    curl_easy_setopt(curl, CURLOPT_URL, server->url.c_str());

    curl_easy_setopt(curl, CURLOPT_PORT, server->port);

    curl_easy_setopt(curl, CURLOPT_PASSWORD, server->password.c_str());

    curl_easy_setopt(curl, CURLOPT_USERNAME, server->user.c_str());

    curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

    mutex = false;
    return SendRpc(BtcRpcPacketPtr(new BtcRpcPacket(connectString))) != NULL;
}
Exemplo n.º 12
0
int OutputTarget::DeactivateMcast (const char *name)
{
	WaitMutex ();
	ACE_OS::memcpy (cmdname, name, ACE_OS::strlen(name));
	cmdname[ACE_OS::strlen(name)] = 0;
	msg_type = 2;
	something_to_send.Post();
	PostMutex ();

	YARPScheduler::yield();

	return YARP_OK;
}
Exemplo n.º 13
0
void
SocketBase::Listen(int iBackLog)
{
    WaitMutex();

    if (listen(iSockDesc, iBackLog) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case EOPNOTSUPP:    throw SocketException(SocketException::errCantListen);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();
}
Exemplo n.º 14
0
void
SocketBase::SetSockOpt(int iCodeLevel, int iOptionName, const void *pOptionData, int iDataLength)
{
    WaitMutex();

    if (setsockopt(iSockDesc, iCodeLevel, iOptionName, pOptionData, iDataLength) < 0)
    {
        ClearMutex();
        switch (errno)
        {
            case EBADF:
            case ENOTSOCK:      throw SocketException(SocketException::errBadDescriptor);
            case ENOPROTOOPT:   throw SocketException(SocketException::errOptionNotSupported);
            case EFAULT:        throw SocketException(SocketException::errIllegalPointer);
            default:            throw SocketException(SocketException::errUnknown, errno);
        }
    }
    ClearMutex();
}
Exemplo n.º 15
0
///
///
/// this is the thread which manages a single output connection.
///
void OutputTarget::Body ()
{
	/// implicit wait mutex for this thread.
	/// see overridden Begin()

#if defined(__QNX6__) || defined(__LINUX__)
	signal (SIGPIPE, SIG_IGN);
#endif
	int success = YARP_OK;
	NewFragmentHeader header;
	BlockSender sender;
	CountedPtr<Sendable> p_local_sendable;

	ACE_OS::memset (cmdname, 0, 2*YARP_STRING_LEN);
	msg_type = 0;

	/// needs to know what is the protocol of the owner.
	switch (protocol_type)
	{
	case YARP_QNET:
		{
			ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : starting a QNET sender thread\n"));

			/// LATER: must do proper bailout if locate fails.
			///
			target_pid = YARPNameService::LocateName (GetLabel().c_str());
			target_pid->setRequireAck(GetRequireAck());
			if (target_pid->getServiceType() != protocol_type)
			{
				/// problems.
				ACE_DEBUG ((LM_DEBUG, "troubles locating %s, the protocol is wrong\n", GetLabel().c_str()));

				YARPNameService::DeleteName(target_pid);
				target_pid = NULL;

				active = 0;
				deactivated = 1;
				PostMutex ();
				return;
			}

			YARPEndpointManager::CreateOutputEndpoint (*target_pid);
			YARPEndpointManager::ConnectEndpoints (*target_pid, own_name);
		}
		break;

	case YARP_TCP:
		{
			ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : starting a TCP sender thread\n"));

			target_pid = YARPNameService::LocateName (GetLabel().c_str(), network_name.c_str());
			target_pid->setRequireAck(GetRequireAck());
			/*
			  There is some kind of hack going on here that
			  prevents a clean use of nameserver (registering
			  ports with the protocol they actually use).
			  Adding a workaround.
			 */
			int use_workaround = 0;
			if (target_pid->isConsistent(YARP_TCP)) {
			  use_workaround = 1;
			}


			if (!(use_workaround||
			      target_pid->isConsistent(YARP_UDP)))
			{
			  if (target_pid->getServiceType()==YARP_NO_SERVICE_AVAILABLE) {
			    ACE_DEBUG ((LM_INFO, "*** FAILED to make connection to %s, port not found\n",GetLabel().c_str()));
			  } else {
			    ACE_DEBUG ((LM_INFO, "***** OutputTarget::Body : can't connect - target on different network, output thread 0x%x bailing out\n", GetIdentifier()));
			  }
				YARPNameService::DeleteName(target_pid);
				target_pid = NULL;

				active = 0;
				deactivated = 1;
				PostMutex ();
				return;	
			}

#ifndef DEBUG_DISABLE_SHMEM
			/// involves a query to dns or to the /etc/hosts file.
			char myhostname[YARP_STRING_LEN];
			getHostname (myhostname, YARP_STRING_LEN);
			ACE_INET_Addr local ((u_short)0, myhostname);

			/// this test is carried out by the nameserver relying on the
			/// subnetwork structure.
			char iplocal[17];
			ACE_OS::memset (iplocal, 0, 17);
			ACE_OS::memcpy (iplocal, local.get_host_addr(), 17);

#ifdef USE_YARP2
			// Test for locality is broken.
			// Is test for same-machine sufficient?
			bool same_machine = YARPNameService::VerifySame (((YARPUniqueNameSock *)target_pid)->getAddressRef().get_host_addr(), iplocal, network_name);
#else
			bool same_machine = YARPNameService::VerifyLocal (((YARPUniqueNameSock *)target_pid)->getAddressRef().get_host_addr(), iplocal, network_name.c_str());
#endif
			///if (((YARPUniqueNameSock *)target_pid)->getAddressRef().get_ip_address() == local.get_ip_address())

			bool accepted = true;

#ifdef USE_YARP2
			// YARP2 extension
			if (same_machine&&allow_shmem) {
			  accepted = (YARPNameService::CheckProperty(GetLabel().c_str(),"accepts", "shmem"))!=0;
			  if (!accepted) {
			    ACE_DEBUG ((LM_DEBUG, "switching to SHMEM mode is prohibited\n"));
			  }
			}
			// YARP2 extension ends			
#endif

			if (same_machine && allow_shmem && accepted)
			{
				/// going into SHMEM mode.
				protocol_type = YARP_SHMEM;
				target_pid->setServiceType (YARP_SHMEM);
				target_pid->setRequireAck(GetRequireAck());

				/// 
				ACE_DEBUG ((LM_DEBUG, "$$$$$ OutputTarget::Body : this goes into SHMEM mode\n"));
			}
			else
#endif
			{
				///
				/// LATER: do proper check. 
				/// 	must always succeed. Any protocol is fine but QNET
				/// 	for creating a socket connection.
				if (target_pid->getServiceType() != protocol_type &&
					target_pid->getServiceType() != YARP_UDP)
				{
					/// problems.
					ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : troubles locating %s, the protocol is wrong\n", GetLabel().c_str()));

					YARPNameService::DeleteName(target_pid);
					target_pid = NULL;

					ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));

					active = 0;
					deactivated = 1;
					PostMutex ();

					return;
					///target_pid->invalidate();
				}

				protocol_type = YARP_TCP;
				target_pid->setServiceType (YARP_TCP);
				target_pid->setRequireAck(GetRequireAck());
			}

			YARPEndpointManager::CreateOutputEndpoint (*target_pid);
			YARPEndpointManager::ConnectEndpoints (*target_pid, own_name);

//#ifdef DEBUG_DISABLE_SHMEM
#	ifdef YARP_TCP_NO_DELAY
			/// disables Nagle's algorithm...
			if (protocol_type == YARP_TCP)
				YARPEndpointManager::SetTCPNoDelay (*target_pid);
#	endif
//#endif
		}
		break;

	case YARP_UDP:
		{
			ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : starting a UDP sender thread\n"));

			target_pid = YARPNameService::LocateName (GetLabel().c_str(), network_name.c_str());
			target_pid->setRequireAck(GetRequireAck());
			if (!target_pid->isConsistent(YARP_UDP))
			{
			  if (target_pid->getServiceType()==YARP_NO_SERVICE_AVAILABLE) {
			    ACE_DEBUG ((LM_INFO, "*** FAILED to make connection to %s, port not found\n",GetLabel().c_str()));
			  } else {
			    ACE_DEBUG ((LM_INFO, "***** OutputTarget::Body : can't connect - target on different network, output thread 0x%x bailing out\n", GetIdentifier()));
			  }
				YARPNameService::DeleteName(target_pid);
				target_pid = NULL;

				active = 0;
				deactivated = 1;
				PostMutex ();

				return;	
			}

#ifndef DEBUG_DISABLE_SHMEM
			char myhostname[YARP_STRING_LEN];
			getHostname (myhostname, YARP_STRING_LEN);
			ACE_INET_Addr local ((u_short)0, myhostname);

			char iplocal[17];
			ACE_OS::memset (iplocal, 0, 17);
			ACE_OS::memcpy (iplocal, local.get_host_addr(), 17);

			/// this test is carried out by the name server.
			bool same_machine = YARPNameService::VerifyLocal (((YARPUniqueNameSock *)target_pid)->getAddressRef().get_host_addr(), iplocal, network_name.c_str());

			///if (((YARPUniqueNameSock *)target_pid)->getAddressRef().get_ip_address() == local.get_ip_address())
			if (same_machine && allow_shmem)
			{
				/// going into SHMEM mode.
				protocol_type = YARP_SHMEM;
				((YARPUniqueNameSock *)target_pid)->setServiceType (YARP_SHMEM);
				target_pid->setRequireAck(GetRequireAck());

				/// 
				ACE_DEBUG ((LM_DEBUG, "$$$$$ OutputTarget::Body : this goes into SHMEM mode\n"));
			}
			else
			{
				/// needed because the port changes from that of the incoming call
				/// it is used to accept data (pretend a connection to the remote).
				if (target_pid->getServiceType() != YARP_UDP)
				{
					/// problems.
					ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : troubles locating %s, the protocol is wrong\n", GetLabel().c_str()));
					YARPNameService::DeleteName(target_pid);
					target_pid = NULL;
	
					ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));

					active = 0;
					deactivated = 1;
					PostMutex ();

					return;	
					///target_pid->invalidate();
				}
			}
#else
			if (target_pid->getServiceType() != YARP_UDP)
			{
				/// problems.
				ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : troubles locating %s, the protocol is wrong\n", GetLabel().c_str()));
				///target_pid->invalidate();
				YARPNameService::DeleteName(target_pid);
				target_pid = NULL;

				ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));

				active = 0;
				deactivated = 1;
				PostMutex ();

				return;	
			}
#endif

			YARPEndpointManager::CreateOutputEndpoint (*target_pid);
			YARPEndpointManager::ConnectEndpoints (*target_pid, own_name);
		}
		break;

	case YARP_MCAST:
		{
			ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : starting a MCAST sender thread\n"));

			/// MCAST is different! Locate prepares the MCAST group and registers it.
			/// additional commands are sent to "clients" to ask to join the specific group.
			/// ALSO: VerifySame had been called before actually running the thread.

			target_pid = YARPNameService::LocateName(GetLabel().c_str(), network_name.c_str(), YARP_MCAST);
			target_pid->setRequireAck(GetRequireAck());
			YARPEndpointManager::CreateOutputEndpoint (*target_pid);

			if (target_pid->getServiceType() != YARP_MCAST)
			{
				/// problems.
				ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : troubles locating %s, the protocol is wrong\n", GetLabel().c_str()));
				///target_pid->invalidate();
				YARPNameService::DeleteName(target_pid);
				target_pid = NULL;
			
				ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));

				active = 0;
				deactivated = 1;
				PostMutex ();

				return;	
			}
		}
		break;
	}

	/// this wait for initialization.
	PostMutex ();
	YARP_DBG(THIS_DBG) ((LM_DEBUG, "Output target after initialization section\n"));

	/// if the address is not valid, terminates the thread.
	if (!target_pid->isValid())
	{
		/// 
		ACE_DEBUG ((LM_DEBUG, "***** OutputTarget, troubles, perhaps a process died without unregistering\n"));
		ACE_DEBUG ((LM_DEBUG, "***** OutputTarget, can't connect to the remote endpoint\n"));

		YARPNameService::DeleteName(target_pid);
		target_pid = NULL;
	
		ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));

		active = 0;
		deactivated = 1;
		PostMutex ();

		return;	
	}

	while (!deactivated)
	{
		YARP_DBG(THIS_DBG) ((LM_DEBUG, "Waiting for sema to send\n"));
		something_to_send.Wait();

		YARP_DBG(THIS_DBG) ((LM_DEBUG, "Done waiting for sema to send\n"));

		WaitMutex();

		if (deactivate)
		{
			active = 0;
			deactivated = 1;
			PostMutex ();
			continue;
		}

		///
		/// MCAST commands follow: 
		///		- these are sent and processed by contacting the TCP channel of the port.
		if (protocol_type == YARP_MCAST)
		{
			/// LATER: need to figure out whether this is always ok.
			/// multiple connection requests might overlap?

			YARP_DBG(THIS_DBG) ((LM_DEBUG, "-------- msg_type is %d\n", msg_type));

			/// process connect/disconnect messages.
			switch (msg_type)
			{
			case 1:
				{
					/// connect
					YARPUniqueNameID* udp_channel = YARPNameService::LocateName(cmdname, network_name.c_str(), YARP_UDP);
					YARPEndpointManager::ConnectEndpoints (*udp_channel, own_name);
					YARPNameService::DeleteName (udp_channel);
				}
				break;

			case 2:
				{
					/// disconnect
					YARPUniqueNameID* udp_channel = YARPNameService::LocateName(cmdname, network_name.c_str(), YARP_UDP);
					if (udp_channel->getServiceType() == YARP_NO_SERVICE_AVAILABLE)
						udp_channel->setName(cmdname);

					/// first tries a Close of the endpoint.
					YARPEndpointManager::Close (*udp_channel);

					/// tests whether a thread termination is required.
					if (YARPEndpointManager::GetNumberOfClients () < 1)
					{
						active = 0;
						deactivated = 1;
					}

					YARPNameService::DeleteName (udp_channel);
				}
				break;

			case 3:
				{
					/// disconnect all
					YARPEndpointManager::CloseMcastAll ();
					active = 0;
					deactivated = 1;	/// perhaps deactivate = 1;
				}
				break;
			}

			/// if a message has been processed jump to the end of thread cycle.
			if (msg_type != 0)
			{
				msg_type = 0;
				PostMutex();
				continue;
			}

		}	/// end of if (protocol_type).


		///
		///
		check_tick = YARPTime::GetTimeAsSeconds();
		ticking = 1;
		p_local_sendable.Set(p_sendable.Ptr());
		p_sendable.Reset();
		
		PostMutex();
		YARP_DBG(THIS_DBG) ((LM_DEBUG, "Waiting for sema to send <<< sema okay!\n"));

		target_pid->getNameID().setRequireAck(GetRequireAck());
		sender.Begin(target_pid->getNameID());
		header.tag = MSG_ID_DATA;
		header.length = 0;
		header.first = 1;
		header.more = 0;
		
		if (add_header)
		{
			sender.Add ((char*)(&header), sizeof(header));
		}

		success = p_local_sendable.Ptr()->Write(sender);
		if (!success)
			YARP_DBG(THIS_DBG) ((LM_DEBUG, "*** Fire failed\n"));
		success = success && sender.End();

		WaitMutex();

		if (deactivate)
		{
			active = 0;
			deactivated = 1;
		}

		if (!success)
		{
			YARP_DBG(THIS_DBG) ((LM_DEBUG, "*** Send failed\n"));
			active = 0;
		}
		
		sending = 0;
		ticking = 0;
		PostMutex();
		p_local_sendable.Reset();
		space_available.Post();

		OnSend();
	} /// while (!deactivated)

	if (protocol_type == YARP_MCAST)
	{
		YARPEndpointManager::CloseMcastAll ();
		/// unregister the mcast group.
		YARPNameService::UnregisterName (target_pid);
	}
	else
	{
		YARPEndpointManager::Close (*target_pid);
	}

	/// but see also what I said on closing the Port thread.
	YARPNameService::DeleteName(target_pid);

	ACE_DEBUG ((LM_DEBUG, "***** OutputTarget::Body : output thread 0x%x bailing out\n", GetIdentifier()));
}
Exemplo n.º 16
0
BtcRpcPacketPtr BtcRpcCurl::SendRpc(BtcRpcPacketPtr jsonString)
{
    if(!curl)
    {
        return BtcRpcPacketPtr();
    }

    WaitMutex();

    BtcRpcPacketPtr receivedData = BtcRpcPacketPtr(new BtcRpcPacket()); // used when receiving data

    /* Now specify we want to POST data */
    curl_easy_setopt(curl, CURLOPT_POST, 1L);

    /* we want to use our own read function (called when sending) */
    curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
    /* pointer to pass to our read function (cointains data to send) */
    curl_easy_setopt(curl, CURLOPT_READDATA, jsonString.get());

    /* we want to use our own write function (called when receiving) */
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
    /* pointer to pass to our write function (we'll write received data into it) */
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, receivedData.get());

    /* get verbose debug output please */
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);

    /*
        If you use POST to a HTTP 1.1 server, you can send data without knowing
        the size before starting the POST if you use chunked encoding. You
        enable this by adding a header like "Transfer-Encoding: chunked" with
        CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
        specify the size in the request.
    */
    #ifdef USE_CHUNKED
    {
        struct curl_slist *chunk = NULL;

        chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
        res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
        /* use curl_slist_free_all() after the *perform() call to free this
            list again */
    }
    #else
        /* Set the expected POST size. If you want to POST large amounts of data,
            consider CURLOPT_POSTFIELDSIZE_LARGE */
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, jsonString->size());
    #endif

    #ifdef DISABLE_EXPECT
    {
        /*
            Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
            header.  You can disable this header with CURLOPT_HTTPHEADER as usual.
            NOTE: if you want chunked transfer too, you need to combine these two
            since you can only set one list of headers with CURLOPT_HTTPHEADER. */

        /* A less good option would be to enforce HTTP 1.0, but that might also
            have other implications. */
        struct curl_slist *chunk = NULL;

        chunk = curl_slist_append(chunk, "Expect:");
        res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
        /* use curl_slist_free_all() after the *perform() call to free this
            list again */
    }
    #endif

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
    {
        fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));

        mutex = false;
        return BtcRpcPacketPtr();
    }

    //if(receivedData->data != NULL)
    //    opentxs::Log::Output(0, receivedData->data);

    // we have to copy the response because for some reason the next few lines set the smart pointer to NULL (?!?!??)
    BtcRpcPacketPtr packetCopy = BtcRpcPacketPtr(new BtcRpcPacket(receivedData));

    receivedData.reset();

    int httpcode = 0;
    curl_easy_getinfo(this->curl, CURLINFO_RESPONSE_CODE, &httpcode);
    if (httpcode == 401)
    {
        std::printf("Error connecting to bitcoind: Wrong username or password\n");
        std::cout.flush();
        mutex = false;
        return BtcRpcPacketPtr();
    }
    else if (httpcode == 500)
    {
        std::printf("Bitcoind internal server error\n");
        std::cout.flush();
        // don't return
    }
    else if (httpcode != 200)
    {
        std::printf("BtcRpc curl error:\nHTTP response code %d\n", httpcode);
        std::cout.flush();
        mutex = false;
        return BtcRpcPacketPtr();
    }

    mutex = false;
    return packetCopy;
}