int ACE_SOCK_Connector::complete (ACE_SOCK_Stream &new_stream, ACE_Addr *remote_sap, const ACE_Time_Value *tv) { ACE_TRACE ("ACE_SOCK_Connector::complete"); ACE_HANDLE h = ACE::handle_timed_complete (new_stream.get_handle (), tv); // We failed to get connected. if (h == ACE_INVALID_HANDLE) { #if defined (ACE_WIN32) // Win32 has a timing problem - if you check to see if the // connection has completed too fast, it will fail - so wait // <ACE_NON_BLOCKING_BUG_DELAY> microseconds to let it catch up // then retry to see if it's a real failure. ACE_Time_Value time (0, ACE_NON_BLOCKING_BUG_DELAY); ACE_OS::sleep (time); h = ACE::handle_timed_complete (new_stream.get_handle (), tv); if (h == ACE_INVALID_HANDLE) { #endif /* ACE_WIN32 */ // Save/restore errno. ACE_Errno_Guard error (errno); new_stream.close (); return -1; #if defined (ACE_WIN32) } #endif /* ACE_WIN32 */ } if (remote_sap != 0) { int len = remote_sap->get_size (); sockaddr *addr = reinterpret_cast<sockaddr *> (remote_sap->get_addr ()); if (ACE_OS::getpeername (h, addr, &len) == -1) { // Save/restore errno. ACE_Errno_Guard error (errno); new_stream.close (); return -1; } } // Start out with non-blocking disabled on the <new_stream>. new_stream.disable (ACE_NONBLOCK); return 0; }
int main() { ACE_INET_Addr server_addr; ACE_SOCK_Acceptor acceptor; ACE_SOCK_Stream peer; if (-1 == server_addr.set(22334)) { log("server_addr.set faild\n"); return 1; } if (-1 == acceptor.open(server_addr)) { log("acceptor.open failed\n"); return 1; } while(1) { if (-1 == acceptor.accept(peer)) { log("acceptor.accept failed\n"); return 1; } peer.disable(ACE_NONBLOCK); auto_ptr<char> pathname(get_url_pathname(&peer)); ACE_Mem_Map mapped_file(pathname.get()); if (-1 == (peer.send_n(mapped_file.addr(), mapped_file.size()))) { log("peer.send_n failed\n"); return 1; } peer.close(); } return acceptor.close() == -1 ? 1 : 0; }
// sets up the dataModeSocket Stream, reads the test header infomation // and launches a thread to handle the requested test. static void run_server (ACE_HANDLE handle) { ACE_INET_Addr cli_addr; // create a new stream and initialized with the handle returned by // accept ACE_SOCK_Stream * dataModeStream = new ACE_SOCK_Stream; dataModeStream->set_handle (handle); // Make sure we're not in non-blocking mode. if (dataModeStream->disable (ACE_NONBLOCK) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("disable"))); return; } else if (dataModeStream->get_remote_addr (cli_addr) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("get_remote_addr"))); return; } // explicity configure Nagling. Default is // Options_Manager::test_enable_nagle=0 so default configurations is // NO NAGLING ACE_CDR::Long nagle; if (Options_Manager::test_enable_nagle) nagle=0; else nagle=1; if (Options_Manager::test_transport_protocol == IPPROTO_SCTP){ // default - sctp case if (-1 == dataModeStream->set_option(IPPROTO_SCTP, SCTP_NODELAY, &nagle, sizeof nagle)){ ACE_ERROR((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("set_option"))); return; } } else { // tcp case if (-1 == dataModeStream->set_option(IPPROTO_TCP, TCP_NODELAY, &nagle, sizeof nagle)){ ACE_ERROR ((LM_ERROR, "%p\n", "set_option")); return; } } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) client %C connected from %d\n"), cli_addr.get_host_name (), cli_addr.get_port_number ())); // hdr bufSize is hardcoded to 8 bytes // (4 for a CDR-encoded boolean and 4 for a CDR-encoded ULong) ACE_CDR::ULong hdrBufSize = 8; // allocate a raw buffer large enough to receive the header and be // properly aligned for the CDR decoding. ACE_CDR::Char * hdrBuf= new ACE_CDR::Char[hdrBufSize+ACE_CDR::MAX_ALIGNMENT]; // align the raw buffer before reading data into it. char * hdrBuf_a = ACE_ptr_align_binary(hdrBuf, ACE_CDR::MAX_ALIGNMENT); size_t bt; // read the header if ((dataModeStream->recv_n(hdrBuf_a, hdrBufSize, 0, &bt)) == -1){ ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("recv_n"))); return; } // pass the CDR encoded data into an ACE_InputCDR class. hdrCDR does // NOT copy this data. Nor does it delete. It assumes the buffer // remains valid while it is in scope. ACE_InputCDR hdrCDR(hdrBuf_a, hdrBufSize); ACE_CDR::Boolean byteOrder; ACE_CDR::ULong numIterations; // extract the data hdrCDR >> ACE_InputCDR::to_boolean (byteOrder); hdrCDR.reset_byte_order(byteOrder); hdrCDR >> numIterations; // make sure the stream is good after the extractions if (!hdrCDR.good_bit()){ ACE_ERROR((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("hdrCDR"))); return; } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Test for %u iterations\n"), numIterations)); // deallocate the header buffer delete[] hdrBuf; // bundle up the arguments ArgStruct * args = new ArgStruct; args->stream = dataModeStream; args->numIters = numIterations; #if defined (ACE_HAS_THREADS) // Spawn a new thread and run the new connection in that thread of // control using the <server> function as the entry point. if (ACE_Thread_Manager::instance ()->spawn (unmarshalledOctetServer, reinterpret_cast<void *> (args), THR_DETACHED) == -1) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("spawn"))); #else (*unmarshalledOctetServer) (reinterpret_cast<void *> (args)); #endif /* ACE_HAS_THREADS */ }
int ACE_SOCK_Connector::shared_connect_finish (ACE_SOCK_Stream &new_stream, const ACE_Time_Value *timeout, int result) { ACE_TRACE ("ACE_SOCK_Connector::shared_connect_finish"); // Save/restore errno. ACE_Errno_Guard error (errno); if (result == -1 && timeout != 0) { // Check whether the connection is in progress. if (error == EINPROGRESS || error == EWOULDBLOCK) { // This expression checks if we were polling. if (timeout->sec () == 0 && timeout->usec () == 0) { #if defined(ACE_WIN32) // In order to detect when the socket that has been // bound to is in TIME_WAIT we need to do the connect // (which will always return EWOULDBLOCK) and then do an // ACE::handle_timed_complete() (with timeout==0, // i.e. poll). This will do a select() on the handle // which will immediately return with the handle in an // error state. The error code is then retrieved with // getsockopt(). Good sockets however will return from // the select() with ETIME - in this case return // EWOULDBLOCK so the wait strategy can complete the // connection. if(ACE::handle_timed_complete (new_stream.get_handle (), timeout) == ACE_INVALID_HANDLE) { int const tmp = errno; if (tmp != ETIME) { error = tmp; } else error = EWOULDBLOCK; } else result = 0; #else /* ACE_WIN32 */ error = EWOULDBLOCK; #endif /* ACE_WIN32 */ } // Wait synchronously using timeout. else if (this->complete (new_stream, 0, timeout) == -1) error = errno; else return 0; } } // EISCONN is treated specially since this routine may be used to // check if we are already connected. if (result != -1 || error == EISCONN) // Start out with non-blocking disabled on the <new_stream>. new_stream.disable (ACE_NONBLOCK); else if (!(error == EWOULDBLOCK || error == ETIMEDOUT)) new_stream.close (); return result; }
/*the accept function*/ static ACE_THR_FUNC_RETURN accept_step1(void *arg) { /*ACE_INET_Addr addr;*/ ACE_SOCK_Stream stream; ACE_HANDLE handle = (ACE_HANDLE)(intptr_t) arg; stream.set_handle(handle); if(stream.disable(ACE_NONBLOCK) == -1){ ACE_ERROR_RETURN((LM_ERROR, "%p\n","get_remote_addr"),0); } /* ACE_DEBUG ((LM_INFO, "(%P|%t) client %s connected from %d\n", addr.get_host_name (), addr.get_port_number ())); */ char* buf = new char[128]; ACE_CString* str = new ACE_CString(); do{ int bytes= stream.recv(buf,128); ACE_DEBUG((LM_INFO, "(%P|%t:%l) bytes = %d\n",bytes)); if(bytes == -1|| bytes == 0){ break; } for(int i=0 ;i < bytes; i++){ *str += buf[i]; } }while(true); delete[] buf; //the input format is '^^pqr->v1$$'; int pos = str->find("->"); int tail = str->find("$$"); ACE_CString* pqr = new ACE_CString(str->substr(2,pos-2)); ACE_CString* pv1 = new ACE_CString(str->substr(pos+2, tail - pos - 2)); ACE_DEBUG((LM_INFO, "(%P|%t:%l) pqr: %s\n pv1:%s\n",pqr->c_str(),pv1->c_str())); bn* _pqr = from_hex(pqr); bn* _v1 = from_hex(pv1); bn* _pr = from_hex(&pr); bn* _r = npmod( _v1, _pr, _pqr); ACE_CString* result = _r->to_hex(); ACE_DEBUG((LM_INFO, "(%P|%t:%l)pqr:%s step1:%s ", pqr->c_str(), result->c_str())); ACE_CString reply = ACE_CString("ack"); stream.send(reply.c_str() , reply.length()); stream.close(); /*send the step1 result to hub:10007 */ ACE_SOCK_Connector connector; ACE_INET_Addr hub_addr(port,hub.c_str()); ACE_DEBUG((LM_DEBUG, "(%P|%t:%l) port:%d host:%s\n", port, hub.c_str())); if(connector.connect(stream, hub_addr) == -1){ ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p\n", "connection failed"), 0); } else ACE_DEBUG ((LM_DEBUG, "(%P|%t) connected to %s at port %d\n", hub_addr.get_host_name (), hub_addr.get_port_number ())); /* * message layout: ^^pqr->digest->senderid$$ */ ACE_CString input = ACE_CString("^^"); input += *pqr; input += "->"; input += *result; input += "->"; input += id ; input += "$$"; ACE_DEBUG((LM_INFO, "(%P|%t:%l) input of step1:%s\n", input.c_str())); if(stream.send(input.c_str(),input.length()) != input.length()){ ACE_ERROR((LM_ERROR, "%p\n","send")); } stream.close(); delete str; delete pqr; delete pv1; delete _pqr; delete _v1; delete _pr; delete _r; delete result; return 0; }
// receive the heartbeat information, and return back the enquened messages; static ACE_THR_FUNC_RETURN commu(void* arg){ ACE_INET_Addr addr; ACE_SOCK_Stream stream; ACE_HANDLE handle =(ACE_HANDLE)(intptr_t) arg; stream.set_handle(handle); if(stream.disable(ACE_NONBLOCK) == -1){ ACE_ERROR_RETURN((LM_ERROR, "%p\n","disable"),0); } else if(stream.get_remote_addr(addr)== -1){ ACE_ERROR_RETURN((LM_ERROR, "%p\n","get_remote_addr"),0); } ACE_DEBUG((LM_INFO, "(%P|%t) client %s connected from %d\n", addr.get_host_name(),addr.get_port_number())); ACE_CString str ; char* ch = new char[128]; do{ int bytes = stream.recv(ch, 128); if(bytes == -1){ ACE_ERROR((LM_ERROR, "%p\n","recv")); break; } if(bytes == 0){ ACE_DEBUG((LM_INFO, "(%P|%t) reached end of input, connection closed by client\n")); break; } for(int i = 0; i< bytes; i++){ str += ch[i]; } }while(true); delete[] ch; ACE_DEBUG((LM_INFO, "received message:%s\n", str.c_str())); /* the layout of the heartbeat message: ^^hb->senderid$$ */ /*if got a heartbeat message*/ int pos = str.find("^^hb->"); if( pos >= 0 ){ int p2 = str.find("$$"); ACE_CString id= str.substr(6, p2 -6); // delete str; ACE_CString sql = "select pqr, v2,txn_id from step2 where recipient='"+ id +"' and transmitted='false' "; ACE_DEBUG((LM_DEBUG, "%s\n", sql.c_str())); PGconn* con; PGresult* res; con = PQconnectdb("dbname=pq"); if(PQstatus(con)!= CONNECTION_OK){ ACE_DEBUG((LM_INFO, "Connection to database failed:%s\n", PQerrorMessage(con))); reclaim_conn(con); } res = PQexec(con, sql.c_str()); int n = PQntuples(res); if(n == 0){ /*no pending messages at all, exit immediately*/ ACE_DEBUG((LM_INFO, "(%P|%t) no pending messages at all\n")); PQclear(res); reclaim_conn(con); stream.close(); // delete str; return 0; } /*there are pending messages*/ else{ /* the reply message is in format "^^pqr1->v1->txn_id1||pqr2->v2->txn_id2||pqr3->v3->txn_id3||$$"*/ ACE_CString reply = ACE_CString("^^"); for(int i=0; i < n ; i++){ reply += PQgetvalue(res, i, 0); reply += "->"; reply += PQgetvalue(res, i, 1); reply += "->"; reply += PQgetvalue(res, i, 2); reply += "||"; } reply += "$$"; PQclear(res); /* reclaim_conn(con); */ stream.send(reply.c_str(), reply.length()); ACE_DEBUG((LM_INFO, "(%P|%t:%l) %s\n", reply.c_str())); ACE_DEBUG((LM_INFO, "(%P|%t) close the writer\n")); stream.close(); // delete str; return 0; } } /*if got an ack message '^^ack->txn_id2||ack->txn_id2||$$' */ int p = str.find("^^ack->"); if( p >= 0){ PGconn* con; PGresult* res; con = PQconnectdb("dbname=pq"); if(PQstatus(con)!= CONNECTION_OK){ ACE_DEBUG((LM_INFO, "Connection to database failed:%s\n", PQerrorMessage(con))); reclaim_conn(con); } do{ p += 7; int p2 = str.find("||",p); if(p2< 0){ ACE_DEBUG((LM_INFO, "reached the end of the txn_ids\n")); break; } ACE_CString txn_id = str.substr(pos, p2 - p); ACE_CString sql = ACE_CString("update step2 set transmitted=TRUE where txn_id='"); sql += txn_id; sql += "'"; ACE_DEBUG((LM_INFO, "(%P|%t:%l) sql:%s\n" , sql.c_str())); res = PQexec(con, sql.c_str()); PQclear(res); p = p2; }while(true); reclaim_conn(con); stream.close(); // delete str; return 0; } return 0; }
static ACE_THR_FUNC_RETURN process(void* arg){ ACE_INET_Addr addr; ACE_SOCK_Stream stream; ACE_HANDLE handle = (ACE_HANDLE) (intptr_t) arg; stream.set_handle(handle); /*make sure we're not in non-blocking mode.*/ if(stream.disable(ACE_NONBLOCK) == -1){ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "disable"), 0); } else if(stream.get_remote_addr(addr) == -1){ ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "get_remote_addr"), 0); } ACE_DEBUG ((LM_INFO, "(%P|%t:%l) client %s connected from %d\n", addr.get_host_name (), addr.get_port_number ())); int r_bytes = 0; char buf[SIZE]; ACE_CString cs; do{ r_bytes = stream.recv(buf, SIZE); if(r_bytes == 0 || r_bytes == -1){ ACE_DEBUG((LM_INFO, "(%P|%t:%l) r_bytes = %d, exit from the loop\n", r_bytes)); break; } for(int i=0; i< r_bytes; i++){ cs += buf[i]; } }while(true); stream.close_reader(); /* ACE_DEBUG((LM_INFO, "%s\n", cs.c_str())); */ /*the layout of the message would be: * ^^pq||step1$$ * 1st step: get the d by pq * 2nd calculate * 3rd send back the digest */ int p0, p1; int len = cs.length(); p0 = 2; p1 = cs.find("||"); ACE_CString pq = cs.substr(2, p1 - 2); ACE_CString step1 = cs.substr(p1 + 2, len - p1 -4); /* ACE_DEBUG((LM_INFO, "pq = %s\n step1 = %s\n", pq.c_str(), step1.c_str())); */ //get the d ACE_CString sql = "select d,textid from player0 where pq='"; sql += pq; sql += "'"; /* ACE_DEBUG((LM_INFO, "sql = %s\n", sql.c_str())); */ PGconn* con; con = PQconnectdb("host=45.33.3.188 port=5432 dbname=nv user=dec"); PGresult* res; if(PQstatus(con)!= CONNECTION_OK){ ACE_DEBUG((LM_INFO, "Connection to database failed:%s\n", PQerrorMessage(con))); reclaim_conn(con); } res = PQexec(con, sql.c_str()); int n = PQntuples(res); if(n != 1){ ACE_ERROR((LM_ERROR, "there is significant error: %d\n", n)); // return 0; } ACE_CString d = ""; d += PQgetvalue(res, 0, 0); /* ACE_DEBUG((LM_INFO, "d = %s\n", d.c_str())); */ bn* pq_ = from_hex(&pq); bn* d_ = from_hex(&d); bn* step1_ = from_hex(&step1); bn* step2_ = npmod(step1_ , d_ , pq_ ); ACE_CString* step2 = step2_->to_hex(); //check if the pq is taking the ownnership? /* if pq is 'centralbank', bypass the check, otherwise check the payer whether has the ownnership of the note; * select count(*) from ownership0 o, player0 p where o.owner = p.textid and o.note='0x12345678' and p.pq='0x12345678'; */ bn* e_ = new bn(1); e_->addat(0,0x10001); bn* step3_ = npmod(step2_ , e_ , pq_ ); ACE_CString* rawMsg = encode(step3_); ACE_DEBUG((LM_INFO, "%T :%l step3 = %s\n", rawMsg->c_str())); if(verify_ownership(rawMsg, pq)){ //update the ownership; int pos1 = rawMsg->find("->"); ACE_CString note = rawMsg->substr(2, pos1 -2); int rawlen = rawMsg->length(); ACE_CString id = rawMsg->substr(pos1 + 2, rawlen - pos1 - 6); update_ownership(note, id); /*insert the log entry*/ insert_logentry(pq, *step2, *rawMsg, note, id); stream.send( step2->c_str(), step2->length()); /* ACE_DEBUG((LM_INFO, "%T :%l the step2 message is:\n%s\n", step2->c_str())); */ }else{ ACE_DEBUG((LM_INFO, "%T :%l invalid transfer\n")); ACE_CString reply ="invalid transfer\n"; stream.send( reply.c_str(), reply.length()); } delete step2 ; delete pq_; delete d_; delete step1_; delete step2_; delete e_; delete step3_; delete rawMsg; /* stream.close_writer(); */ stream.close(); ACE_DEBUG((LM_INFO, "%T :%l closed the stream\n")); }