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; }
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); }
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; }
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; }
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); }
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); }
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(); }
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; }
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(); }
int OutputTarget::DeactivateMcastAll (void) { WaitMutex (); msg_type = 3; something_to_send.Post(); PostMutex (); /// I may actually join here! YARPScheduler::yield(); return YARP_OK; }
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; }
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; }
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(); }
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(); }
/// /// /// 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())); }
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; }