int main(int argc, char **argv) { SOCKET s; char *remote; if(argc > 1) remote = argv[1]; else remote = REMOTE_ADDR; printf("Starting Winsock... "); if(StartWinsock() != 0) { printf("Failed.\n"); return EXIT_FAILURE; } printf("OK.\n"); printf("Connecting to %s:%d... ", remote, SERVER_PORT); if((s = CreateConnectSocket(remote, SERVER_PORT)) == SOCKET_ERROR) { printf("Failed.\n"); return EXIT_FAILURE; } printf("OK.\n\n"); if(ClientHandshake(s)) CommandLoop(s); WSACleanup(); if(conn.dh_remote_key) free(conn.dh_remote_key); if(conn.dh_shared_key) free(conn.dh_shared_key); if(conn.nonce) free(conn.nonce); #ifdef _DEBUG showmemstats(stdout); #endif return EXIT_SUCCESS; }
//Ö§³Öhost name //ÄÚ²¿º¯Êý ͨ¹ý½Ó¿Ú½á¹¹Ìå»ñÈ¡SOCKET ID //Èë²Î thisÖ¸Õ룬 ·µ»ØÖµ SOCKET ID (OR INVALID SOCKET) SOCKET IpappGetSocketId(IPAPP_USER_S* pThis) { //Èë²Î¼ì²é CHECK_PARAM(pThis); UINT32 uiRet = VOS_OK; char* pcAddr = NULL; //SOCKET soSocket = 0; struct hostent *remoteHost = NULL; if (!pThis->bsocketid) { if(!pThis->bip) { remoteHost = gethostbyname(pThis->hostname); if (remoteHost == NULL) { uiRet = WSAGetLastError(); printf("Function failed with error: %ld\n", uiRet); return VOS_ERROR; } pcAddr = inet_ntoa (*(struct in_addr *)*remoteHost->h_addr_list); } else { pcAddr = pThis->ip; } return CreateConnectSocket(pThis->usPort, (const char *) pcAddr); } return pThis->socketid; }
bool TClient::Init() { InitializeCriticalSection(&m_CS); int rv; WSADATA wsa; if( WSAStartup( MAKEWORD(2,2), &wsa ) != 0 ) { return -1; } if( CreateConnectSocket( 10000 ) == 0 ) { // send thread unsigned sendThread, receiveThread; m_hSendThread = _beginthreadex( NULL, 0, sendMessage, (void*)this, 0, &sendThread); // recv thread m_hReceiveThread = _beginthreadex( NULL, 0, receiveMessage, (void*)this, 0, &receiveThread); } return true; }
int test_mid_clt(int ctlSocket, char tests, char* host, int conn_options, int buf_size, char* tmpstr2) { char buff[BUFFSIZE+1]; int msgLen, msgType; int midport = 3003; I2Addr sec_addr = NULL; int ret, one=1, i, inlth; int in2Socket; double t, spdin; uint32_t bytes; struct timeval sel_tv; fd_set rfd; if (tests & TEST_MID) { log_println(1, " <-- Middlebox test -->"); msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed prepare message!"); return 1; } if (check_msg_type("Middlebox test", TEST_PREPARE, msgType, buff, msgLen)) { return 2; } if (msgLen <= 0) { log_println(0, "Improper message"); return 3; } buff[msgLen] = 0; if (check_int(buff, &midport)) { log_println(0, "Invalid port number"); return 4; } log_println(1, " -- port: %d", midport); if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) { log_println(0, "Unable to resolve server address: %s", strerror(errno)); return -3; } I2AddrSetPort(sec_addr, midport); if (get_debuglvl() > 4) { char tmpbuff[200]; size_t tmpBufLen = 199; memset(tmpbuff, 0, 200); I2AddrNodeName(sec_addr, tmpbuff, &tmpBufLen); log_println(5, "connecting to %s:%d", tmpbuff, I2AddrPort(sec_addr)); } if ((ret = CreateConnectSocket(&in2Socket, NULL, sec_addr, conn_options, buf_size))) { log_println(0, "Connect() for middlebox failed: %s", strerror(errno)); return -10; } printf("Checking for Middleboxes . . . . . . . . . . . . . . . . . . "); fflush(stdout); tmpstr2[0] = '\0'; i = 0; bytes = 0; t = secs() + 5.0; sel_tv.tv_sec = 6; sel_tv.tv_usec = 5; FD_ZERO(&rfd); FD_SET(in2Socket, &rfd); for (;;) { if (secs() > t) break; ret = select(in2Socket+1, &rfd, NULL, NULL, &sel_tv); if (ret > 0) { inlth = read(in2Socket, buff, sizeof(buff)); if (inlth == 0) break; bytes += inlth; continue; } if (ret < 0) { printf("nothing to read, exiting read loop\n"); break; } if (ret == 0) { printf("timer expired, exiting read loop\n"); break; } } t = secs() - t + 5.0; spdin = ((8.0 * bytes) / 1000) / t; msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed text message!"); return 1; } if (check_msg_type("Middlebox test results", TEST_MSG, msgType, buff, msgLen)) { return 2; } strncat(tmpstr2, buff, msgLen); memset(buff, 0, 128); sprintf(buff, "%0.0f", spdin); log_println(4, "CWND limited speed = %0.2f kbps", spdin); send_msg(ctlSocket, TEST_MSG, buff, strlen(buff)); printf("Done\n"); I2AddrFree(sec_addr); msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed finalize message!"); return 1; } if (check_msg_type("Middlebox test", TEST_FINALIZE, msgType, buff, msgLen)) { return 2; } log_println(1, " <-------------------->"); } return 0; }
int test_s2c_clt(int ctlSocket, char tests, char* host, int conn_options, int buf_size, char* tmpstr) { char buff[BUFFSIZE+1]; int msgLen, msgType; int s2cport = 3003; I2Addr sec_addr = NULL; int inlth, ret, one=1, set_size; int inSocket; socklen_t optlen; uint32_t bytes; double t; struct timeval sel_tv; fd_set rfd; char* ptr; if (tests & TEST_S2C) { log_println(1, " <-- S2C throughput test -->"); msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed prepare message!"); return 1; } if (check_msg_type("S2C throughput test", TEST_PREPARE, msgType, buff, msgLen)) { return 2; } if (msgLen <= 0) { log_println(0, "Improper message"); return 3; } buff[msgLen] = 0; if (check_int(buff, &s2cport)) { log_println(0, "Invalid port number"); return 4; } log_println(1, " -- port: %d", s2cport); /* Cygwin seems to want/need this extra getsockopt() function * call. It certainly doesn't do anything, but the S2C test fails * at the connect() call if it's not there. 4/14/05 RAC */ optlen = sizeof(set_size); getsockopt(ctlSocket, SOL_SOCKET, SO_SNDBUF, &set_size, &optlen); if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) { log_println(0, "Unable to resolve server address: %s", strerror(errno)); return -3; } I2AddrSetPort(sec_addr, s2cport); if ((ret = CreateConnectSocket(&inSocket, NULL, sec_addr, conn_options, buf_size))) { log_println(0, "Connect() for Server to Client failed", strerror(errno)); return -15; } setsockopt(inSocket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); /* Linux updates the sel_tv time values everytime select returns. This * means that eventually the timer will reach 0 seconds and select will * exit with a timeout signal. Other OS's don't do that so they need * another method for detecting a long-running process. The check below * will cause the loop to terminate if select says there is something * to read and the loop has been active for over 14 seconds. This usually * happens when there is a problem (duplex mismatch) and there is data * queued up on the server. */ msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed start message!"); return 1; } if (check_msg_type("S2C throughput test", TEST_START, msgType, buff, msgLen)) { return 2; } printf("running 10s inbound test (server to client) . . . . . . "); fflush(stdout); bytes = 0; t = secs() + 15.0; sel_tv.tv_sec = 15; sel_tv.tv_usec = 5; FD_ZERO(&rfd); FD_SET(inSocket, &rfd); for (;;) { ret = select(inSocket+1, &rfd, NULL, NULL, &sel_tv); if (secs() > t) { log_println(5, "Receive test running long, break out of read loop"); break; } if (ret > 0) { inlth = read(inSocket, buff, sizeof(buff)); if (inlth == 0) break; bytes += inlth; continue; } if (get_debuglvl() > 5) { log_println(0, "s2c read loop exiting:", strerror(errno)); } break; } t = secs() - t + 15.0; spdin = ((8.0 * bytes) / 1000) / t; /* receive the s2cspd from the server */ msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed text message!"); return 1; } if (check_msg_type("S2C throughput test", TEST_MSG, msgType, buff, msgLen)) { return 2; } if (msgLen <= 0) { log_println(0, "Improper message"); return 3; } buff[msgLen] = 0; ptr = strtok(buff, " "); if (ptr == NULL) { log_println(0, "S2C: Improper message"); return 4; } s2cspd = atoi(ptr); ptr = strtok(NULL, " "); if (ptr == NULL) { log_println(0, "S2C: Improper message"); return 4; } ssndqueue = atoi(ptr); ptr = strtok(NULL, " "); if (ptr == NULL) { log_println(0, "S2C: Improper message"); return 4; } sbytes = atoi(ptr); if (spdin < 1000) printf("%0.2f kb/s\n", spdin); else printf("%0.2f Mb/s\n", spdin/1000); I2AddrFree(sec_addr); sprintf(buff, "%0.0f", spdin); send_msg(ctlSocket, TEST_MSG, buff, strlen(buff)); /* get web100 variables from server */ tmpstr[0] = '\0'; for (;;) { msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed text/finalize message!"); return 1; } if (msgType == TEST_FINALIZE) { break; } if (check_msg_type("S2C throughput test", TEST_MSG, msgType, buff, msgLen)) { return 2; } strncat(tmpstr, buff, msgLen); log_println(6, "tmpstr = '%s'", tmpstr); } log_println(1, " <------------------------->"); } return 0; }
int CMainCtrl::CheckSvrMessage() { int iDoMsgCnt = 0; int iDoMsgLen = 0; int iCodeLength; char *pMsgBuff; int iGetPtrLen = -1; while((iDoMsgLen < 500*1024) && (iDoMsgCnt < 500)) { ssize_t iBuffUsed,iBuffCount,iObjUsed,iObjCount; m_stBuffMngRecv.GetBufferUsage(iBuffUsed,iBuffCount,iObjUsed,iObjCount); //空间已满 if(iObjUsed/(float)iObjCount > 0.9) { //少数连接比较慢 if(iBuffUsed/(float)iBuffCount > 0.5) break; } if(iGetPtrLen > 0) { m_Svr2MePipe.SkipHeadCodePtr(); iGetPtrLen = -1; } iGetPtrLen = m_Svr2MePipe.GetHeadCodePtr(pMsgBuff, &iCodeLength); if(iGetPtrLen < 0) { iCodeLength = sizeof(m_szCodeBuff); int iRet = m_Svr2MePipe.GetHeadCode(m_szCodeBuff, &iCodeLength); if(iRet < 0 || iCodeLength <= 0) { break; } pMsgBuff = m_szCodeBuff; } else if(iGetPtrLen == 0) { break; } iDoMsgLen += iCodeLength; iDoMsgCnt++; char *pClientMsg = pMsgBuff + sizeof(TMQHeadInfo); int iClientMsgLen = iCodeLength - sizeof(TMQHeadInfo); TMQHeadInfo* pMQHeadInfo = (TMQHeadInfo*)pMsgBuff; //请求关闭 if(pMQHeadInfo->m_ucCmd == TMQHeadInfo::CMD_REQ_SCC_CLOSE) { ClearSocketNode(pMQHeadInfo->m_unClientIP,pMQHeadInfo->m_usClientPort,pMQHeadInfo->m_szSrcMQ); continue; } //必须是连接或者传输包 if ((pMQHeadInfo->m_ucCmd != TMQHeadInfo::CMD_REQ_SCC_CONN) && (pMQHeadInfo->m_ucCmd != TMQHeadInfo::CMD_DATA_TRANS)) { TLib_Log_LogMsg("ERR:Bad MQ cmd id %d from server!\n",pMQHeadInfo->m_ucCmd); continue; } //检查接收队列中的超时包 if(m_stConfig.m_iMaxQueueWaitus) { gettimeofday(&m_tNow,NULL); int iQueueWaitus = (m_tNow.tv_sec - pMQHeadInfo->m_tTimeStampSec)*1000000+ (m_tNow.tv_usec - pMQHeadInfo->m_tTimeStampuSec); if(iQueueWaitus>m_stConfig.m_iMaxQueueWaitus) { TLib_Log_LogMsgFrequency(1,"WARN::Expire Msg From Mem Queue, QueueWait=%dus\n",iQueueWaitus); } } char szKey[1024]; ssize_t iKeyLen = 0; if(pMQHeadInfo->m_ucDataType == TMQHeadInfo::DATA_TYPE_UDP) { iKeyLen = (ssize_t)MakeKey(0,0,pMQHeadInfo->m_szSrcMQ,szKey); ssize_t iNodeObjIdx = -1; TSocketNode* pSocketNode = (TSocketNode*)m_stSocketNodeHash.GetObjectByKey((void *)szKey,iKeyLen,iNodeObjIdx); if (!pSocketNode) { int iSocket = CreateConnectSocket(0,0, m_stConfig.SOCKET_RCVBUF,m_stConfig.SOCKET_SNDBUF,1); if (iSocket < 0) { char szIPAddr[32]={0}; NtoP(pMQHeadInfo->m_unClientIP,szIPAddr); TLib_Log_LogMsg("ERR:UDP connect to %s:%d failed![%s:%d]\n", szIPAddr,pMQHeadInfo->m_usClientPort,__FILE__,__LINE__); continue; } iNodeObjIdx = CreateSocketNode(iSocket,TSocketNode::STATUS_OK, 0,0,pMQHeadInfo->m_szSrcMQ,TSocketNode::UDP_SOCKET); if (iNodeObjIdx < 0) { close(iSocket); TLib_Log_LogMsg("ERR:UDP Add to socket array failed!SocketNodeMng used %d, free %d\n", m_stSocketNodeMng.GetUsedCount(),m_stSocketNodeMng.GetFreeCount()); continue; } pSocketNode = (TSocketNode*)m_stSocketNodeHash.GetObjectByIdx(iNodeObjIdx); } else if(pSocketNode->m_sSocketType != TSocketNode::UDP_SOCKET) { TLib_Log_LogMsg("ERR:MQ name %d alread exist! and its type is %d, not UDP socket.\n", pSocketNode->m_szSrcMQ,(int)pSocketNode->m_sSocketType); continue; } struct sockaddr_in addrClient; addrClient.sin_family = AF_INET; addrClient.sin_addr.s_addr = pMQHeadInfo->m_unClientIP; addrClient.sin_port = htons(pMQHeadInfo->m_usClientPort); int iSendBytes = sendto(pSocketNode->m_iSocket,pClientMsg,iClientMsgLen, 0,(struct sockaddr*)&addrClient,sizeof(struct sockaddr_in)); pSocketNode->m_iActiveTime = m_tNow.tv_sec; if(iSendBytes > 0) { m_stStat.m_llUdpSCSuccPkgNum++; m_stStat.m_llUdpSCPkgLen += iClientMsgLen; } else { TLib_Log_LogMsg("ERR:Udp sendto failed ret=%d.[%s:%d]\n",iSendBytes,__FILE__,__LINE__); m_stStat.m_llUdpSCFailedPkgNum++; } } else { iKeyLen = (ssize_t)MakeKey(pMQHeadInfo->m_unClientIP,pMQHeadInfo->m_usClientPort,pMQHeadInfo->m_szSrcMQ,szKey); ssize_t iNodeObjIdx = -1; TSocketNode* pSocketNode = (TSocketNode*)m_stSocketNodeHash.GetObjectByKey((void *)szKey,iKeyLen,iNodeObjIdx); if (!pSocketNode) { //连接不存在 int iSocket = CreateConnectSocket(pMQHeadInfo->m_unClientIP,pMQHeadInfo->m_usClientPort, m_stConfig.SOCKET_RCVBUF,m_stConfig.SOCKET_SNDBUF,0); if (iSocket < 0) { char szIPAddr[32]={0}; NtoP(pMQHeadInfo->m_unClientIP,szIPAddr); TLib_Log_LogMsg("ERR:connect to %s:%d failed![%s:%d]\n", szIPAddr,pMQHeadInfo->m_usClientPort,__FILE__,__LINE__); continue; } int iSocketStatus = TSocketNode::STATUS_CONNECTING; if (pMQHeadInfo->m_ucCmd == TMQHeadInfo::CMD_DATA_TRANS) iSocketStatus = TSocketNode::STATUS_SENDING; iNodeObjIdx = CreateSocketNode(iSocket,iSocketStatus, pMQHeadInfo->m_unClientIP, pMQHeadInfo->m_usClientPort, pMQHeadInfo->m_szSrcMQ,TSocketNode::TCP_SOCKET); if (iNodeObjIdx < 0) { close(iSocket); TLib_Log_LogMsg("ERR:Add to socket array failed!SocketNodeMng used %d, free %d\n", m_stSocketNodeMng.GetUsedCount(),m_stSocketNodeMng.GetFreeCount()); continue; } pSocketNode = (TSocketNode*)m_stSocketNodeHash.GetObjectByIdx(iNodeObjIdx); } else if (pMQHeadInfo->m_ucCmd == TMQHeadInfo::CMD_REQ_SCC_CONN) { //连接存在 TMQHeadInfo stMQHeadInfo; FillMQHead(&stMQHeadInfo,pSocketNode,TMQHeadInfo::CMD_SCC_RSP_CONNSUCC); m_Me2SvrPipe.AppendOneCode((const char *)&stMQHeadInfo, sizeof(TMQHeadInfo)); continue; } //试图发送 int iSendBytes = m_stBuffMngSend.SendBufferToSocket(pSocketNode->m_iSocket,iNodeObjIdx); if ((iSendBytes<0)&&(errno!=EAGAIN)) { TLib_Log_LogMsg("ERR:write() to socket failed,ret %d,errno=%d,socket %d,clientmsglen %d[%s:%d].\n", iSendBytes,errno,pSocketNode->m_iSocket,iClientMsgLen,__FILE__,__LINE__); ClearSocketNode(pSocketNode->m_unClientIP,pSocketNode->m_usClientPort,pSocketNode->m_szSrcMQ); continue; } //数据传输,缓存没有则直接发送,有则放入缓存 if (m_stBuffMngSend.GetBufferSize(iNodeObjIdx) <= 0) { int iSendBytes = write(pSocketNode->m_iSocket, pClientMsg, iClientMsgLen); if ((iSendBytes<0)&&(errno!=EAGAIN)) { TLib_Log_LogMsg("ERR:write() to socket failed,ret %d,errno=%d,socket %d,clientmsglen %d[%s:%d]\n", iSendBytes,errno,pSocketNode->m_iSocket,iClientMsgLen,__FILE__,__LINE__); ClearSocketNode(pMQHeadInfo->m_unClientIP,pMQHeadInfo->m_usClientPort,pSocketNode->m_szSrcMQ); continue; } else if (iSendBytes < iClientMsgLen) { iSendBytes = iSendBytes>0 ? iSendBytes : 0; if (0==m_stBuffMngSend.AppendBuffer(iNodeObjIdx, pClientMsg+iSendBytes,iClientMsgLen-iSendBytes)) { //增加EPOLLOUT监控 m_stEPollFlow.Modify(pSocketNode->m_iSocket, iNodeObjIdx, EPOLLIN |EPOLLOUT| EPOLLERR|EPOLLHUP); } else { //已经发了一部分,防止数据错乱,关闭 ClearSocketNode(pSocketNode->m_unClientIP,pSocketNode->m_usClientPort,pSocketNode->m_szSrcMQ); TLib_Log_LogMsg("ERR:AppendBuffer() failed,BuffMngSend may be full,close link![%s:%d]\n",__FILE__,__LINE__); continue; } } } else { if(m_stBuffMngSend.AppendBuffer(iNodeObjIdx, pClientMsg,iClientMsgLen)) { //不能秘密丢包,关闭连接,使外界感知 ClearSocketNode(pSocketNode->m_unClientIP,pSocketNode->m_usClientPort,pSocketNode->m_szSrcMQ); TLib_Log_LogMsgFrequency(1,"ERR:AppendBuffer() failed,BuffMngSend may be full, close link![%s:%d]\n",__FILE__,__LINE__); continue; } } pSocketNode->m_iActiveTime = m_tNow.tv_sec; m_stStat.m_llTcpSCPkgNum++; m_stStat.m_llTcpSCPkgLen += (unsigned int)iClientMsgLen; } m_pCLoadGrid->CheckLoad(m_tNow); } if(iGetPtrLen > 0) { m_Svr2MePipe.SkipHeadCodePtr(); iGetPtrLen = -1; } return 0; }
/** * Perform the client part of the middleBox testing. The middlebox test * is a 5.0 second throughput test from the Server to the Client to * check for duplex mismatch conditions. It determines if routers or * switches in the path may be making changes to some TCP parameters. * @param ctlSocket server control socket descriptor * @param tests set of tests to perform * @param host hostname of the server * @param conn_options connection options * @param buf_size TCP send/receive buffer size * @param testresult_str result obtained from server (containing server ip, * client ip, currentMSS, WinSCaleSent, WinScaleRcvd) * @param jsonSupport Indicates if messages should be sent using JSON format * @return integer * => 0 on success * < 0 if error * Return codes used: * 0 = (the test has been finalized) * > 0 if protocol interactions were not as expected: * 1: Unable to receive protocol message successfully * 2: Wrong message type received * 3: Protocol message received was of invalid length * 4: Protocol payload data received was invalid * 5: Protocol message received was invalid * < 0 if generic error: * -3: Unable to resolve server address * -10: creating connection to server failed * */ int test_mid_clt(int ctlSocket, char tests, char* host, int conn_options, int buf_size, char* testresult_str, int jsonSupport) { char buff[BUFFSIZE + 1]; int msgLen, msgType; int midport = atoi(PORT3); I2Addr sec_addr = NULL; int retcode, inlth; int in2Socket; double t, spdin; uint32_t bytes; struct timeval sel_tv; fd_set rfd; char* jsonMsgValue; enum TEST_STATUS_INT teststatuses = TEST_NOT_STARTED; enum TEST_ID testids = MIDDLEBOX; if (tests & TEST_MID) { // middlebox test has to be performed log_println(1, " <-- Middlebox test -->"); setCurrentTest(TEST_MID); // protocol logs teststatuses = TEST_STARTED; protolog_status(getpid(), testids, teststatuses, ctlSocket); // Initially, expecting a TEST_PREPARE message. Any other message // ..type is unexpected at this stage. msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed prepare message!"); return 1; } if (check_msg_type(MIDBOX_TEST_LOG, TEST_PREPARE, msgType, buff, msgLen)) { return 2; } // The server is expected to send a message with a valid payload that // contains the port number that server wants client to bind to for this // test buff[msgLen] = 0; if (jsonSupport) { jsonMsgValue = json_read_map_value(buff, DEFAULT_KEY); strlcpy(buff, jsonMsgValue, sizeof(buff)); msgLen = strlen(buff); free(jsonMsgValue); } if (msgLen <= 0) { log_println(0, "Improper message"); return 3; } if (check_int(buff, &midport)) { // obtained message does not contain // integer port# log_println(0, "Invalid port number"); return 4; } // get server address and set port log_println(1, " -- port: %d", midport); if ((sec_addr = I2AddrByNode(get_errhandle(), host)) == NULL) { log_println(0, "Unable to resolve server address: %s", strerror(errno)); return -3; } I2AddrSetPort(sec_addr, midport); // debug to check if correct port was set in addr struct if (get_debuglvl() > 4) { char tmpbuff[200]; size_t tmpBufLen = 199; memset(tmpbuff, 0, 200); I2AddrNodeName(sec_addr, tmpbuff, &tmpBufLen); log_println(5, "connecting to %s:%d", tmpbuff, I2AddrPort(sec_addr)); } // connect to server using port obtained above if ((retcode = CreateConnectSocket(&in2Socket, NULL, sec_addr, conn_options, buf_size))) { log_println(0, "Connect() for middlebox failed: %s", strerror(errno)); return -10; } // start reading throughput test data from server using the connection // created above printf("Checking for Middleboxes . . . . . . . . . . . . . . . . . . "); fflush(stdout); testresult_str[0] = '\0'; bytes = 0; t = secs() + 5.0; // set timer for 5 seconds, and read for 5 seconds sel_tv.tv_sec = 6; // Time out the socket after 6.5 seconds sel_tv.tv_usec = 5; // 500? FD_ZERO(&rfd); FD_SET(in2Socket, &rfd); for (;;) { if (secs() > t) break; retcode = select(in2Socket+1, &rfd, NULL, NULL, &sel_tv); if (retcode > 0) { inlth = read(in2Socket, buff, sizeof(buff)); if (inlth == 0) break; bytes += inlth; continue; } if (retcode < 0) { printf("nothing to read, exiting read loop\n"); break; } if (retcode == 0) { printf("timer expired, exiting read loop\n"); break; } } // get actual time for which test was run t = secs() - t + 5.0; // calculate throughput in Kbps spdin = ((BITS_8_FLOAT * bytes) / KILO) / t; // Test is complete. Now, get results from server (includes CurrentMSS, // WinScaleSent, WinScaleRcvd..). // The results are sent from server in the form of a TEST_MSG object msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed text message!"); return 1; } if (check_msg_type(MIDBOX_TEST_LOG " results", TEST_MSG, msgType, buff, msgLen)) { return 2; } buff[msgLen] = 0; strlcat(testresult_str, buff, MIDBOX_TEST_RES_SIZE); memset(buff, 0, sizeof(buff)); // this should work since the throughput results from the server should // ...fit well within BUFFSIZE snprintf(buff, sizeof(buff), "%0.0f", spdin); log_println(4, "CWND limited speed = %0.2f kbps", spdin); // client now sends throughput it calculated above to server, as a TEST_MSG send_json_message(ctlSocket, TEST_MSG, buff, strlen(buff), jsonSupport, JSON_SINGLE_VALUE); printf("Done\n"); I2AddrFree(sec_addr); // Expect an empty TEST_FINALIZE message from server msgLen = sizeof(buff); if (recv_msg(ctlSocket, &msgType, buff, &msgLen)) { log_println(0, "Protocol error - missed finalize message!"); return 1; } if (check_msg_type(MIDBOX_TEST_LOG, TEST_FINALIZE, msgType, buff, msgLen)) { return 2; } log_println(1, " <-------------------->"); // log protocol test ending teststatuses = TEST_ENDED; protolog_status(getpid(), testids, teststatuses, ctlSocket); setCurrentTest(TEST_NONE); } return 0; }