INT32 SNTPClient::Connect() { SOCK_SOCKET timeSocket = SOCK_SOCKET_ERROR; INT32 sockErr = 0; UINT32 usedServer = 0; // look up outstdanding queries for this set of servers OutstandingQuery* query = FindOutstandingConnection(m_ipAddressPrimary, m_ipAddressAlternate); if(query != NULL) { // // signal failed queries // if(query->IsOld()) { query->Dispose(); query = NULL; } else { // // resume old connection // timeSocket = query->GetSocket(); } } if(timeSocket == SOCK_SOCKET_ERROR) { // // new connection // timeSocket = SOCK_socket(SOCK_AF_INET, SOCK_SOCK_DGRAM, SOCK_IPPROTO_UDP); if(timeSocket == SOCK_SOCKET_ERROR) { sockErr = SOCK_getlasterror(); return (sockErr == 0 ? HAL_TIMESERVICE_ERROR : sockErr); } SOCK_sockaddr addr; SOCK_sockaddr_in* dst = (SOCK_sockaddr_in*)&addr; memset(dst, 0, sizeof(SOCK_sockaddr_in)); dst->sin_family = SOCK_AF_INET; dst->sin_port = SOCK_htons(123); dst->sin_addr.S_un.S_addr = SOCK_htonl(m_ipAddressPrimary); usedServer = m_ipAddressPrimary; if(SOCK_connect(timeSocket, &addr, sizeof(addr)) == SOCK_SOCKET_ERROR && SOCK_getlasterror() != SOCK_EWOULDBLOCK) { if(m_ipAddressAlternate != 0) { usedServer = m_ipAddressAlternate; dst->sin_addr.S_un.S_addr = SOCK_htonl(m_ipAddressAlternate); if(SOCK_connect(timeSocket, &addr, sizeof(addr)) == SOCK_SOCKET_ERROR && SOCK_getlasterror() != SOCK_EWOULDBLOCK) { sockErr = SOCK_getlasterror(); SOCK_close(timeSocket); return (sockErr == 0 ? HAL_TIMESERVICE_ERROR : sockErr); } } else { sockErr = SOCK_getlasterror(); SOCK_close(timeSocket); return (sockErr == 0 ? HAL_TIMESERVICE_ERROR : sockErr); } } Initialize(); int sent = SOCK_send(timeSocket, (char*)SNTPData, sizeof(SNTPData), 0); if(sent != sizeof(SNTPData)) { sockErr = SOCK_getlasterror(); SOCK_close(timeSocket); return (sockErr == 0 ? HAL_TIMESERVICE_ERROR : sockErr); } } // retry 10 times every time we stop by INT32 retry = 10; INT32 bytesToRead = c_SNTPDataLength; char* buf = (char*)SNTPData; while(retry-- > 0) { int read = SOCK_recv(timeSocket, buf, bytesToRead, 0); if(read < 0 && (sockErr = SOCK_getlasterror()) != SOCK_EWOULDBLOCK) { SOCK_close(timeSocket); return (sockErr == 0 ? HAL_TIMESERVICE_ERROR : sockErr); } else if(read > 0) { bytesToRead -= read; if(bytesToRead <= 0) { break; } buf += read; // incase we start receiving data towards the end // of the retry limit. retry++; } } // if we could not finish reading, then cache and retry later // if we read a part of answer, then declare failure // in the future we could try and cope with this problem if(bytesToRead == c_SNTPDataLength) { // // if this is a new connection, get a slot // if(query == NULL) { query = GetQuery(usedServer, timeSocket); } return HAL_TIMESERVICE_WANT_READ_WRITE; } else if(bytesToRead > 0 && bytesToRead < c_SNTPDataLength) { if(query != NULL) query->Dispose(); return HAL_TIMESERVICE_WANT_READ_WRITE; } else { if(query != NULL) { query->Dispose(); query = NULL; } else { if( timeSocket != SOCK_SOCKET_ERROR ) { SOCK_close(timeSocket); timeSocket = SOCK_SOCKET_ERROR; } } } DestinationTimestamp = Time_GetUtcTime(); if( !IsResponseValid() ) { if(query != NULL) { query->Dispose(); query = NULL; } else { if( timeSocket != SOCK_SOCKET_ERROR ) { SOCK_close(timeSocket); timeSocket = SOCK_SOCKET_ERROR; } } return HAL_TIMESERVICE_ERROR; } return HAL_TIMESERVICE_SUCCESS; }
BOOL RTIP_SOCKETS_Driver::Initialize() { NATIVE_PROFILE_PAL_NETWORK(); IFACE_INFO info; memset(g_RTIP_SOCKETS_Driver.m_interfaces, 0, sizeof(g_RTIP_SOCKETS_Driver.m_interfaces)); /* Initialize the network stack */ if (rtp_net_init() != 0) { DEBUG_HANDLE_SOCKET_ERROR("rtp_net_init", TRUE); return FALSE; } #if defined(NETWORK_USE_LOOPBACK) // Bind and Open the loopback driver g_LOOPBACK_Driver.Bind(); if (g_LOOPBACK_Driver.Open() == SOCK_SOCKET_ERROR) { DEBUG_HANDLE_SOCKET_ERROR("loopback init", FALSE); } #endif for(int i=0; i<g_NetworkConfig.NetworkInterfaceCount; i++) { int interfaceNumber; SOCK_NetworkConfiguration *pNetCfg = &g_NetworkConfig.NetworkInterfaces[i]; Network_Interface_Bind(i); interfaceNumber = Network_Interface_Open(i); if (interfaceNumber == SOCK_SOCKET_ERROR) { DEBUG_HANDLE_SOCKET_ERROR("Network init", FALSE); debug_printf("SocketError: %d\n", xn_getlasterror()); continue; } g_RTIP_SOCKETS_Driver.m_interfaces[i].m_interfaceNumber = interfaceNumber; UpdateAdapterConfiguration(i, SOCK_NETWORKCONFIGURATION_UPDATE_DHCP | SOCK_NETWORKCONFIGURATION_UPDATE_DNS, pNetCfg); // default debugger interface if(0 == i) { // add multicast addresses to the routing table UINT32 mcast1 = SOCK_htonl(SOCK_DISCOVERY_MULTICAST_IPADDR); UINT32 mcast2 = SOCK_htonl(SOCK_DISCOVERY_MULTICAST_IPADDR_SND); UINT32 mask = SOCK_htonl(SOCK_MAKE_IP_ADDR(255,255,255,255)); if(SOCK_SOCKET_ERROR == xn_rt_add((RTP_PFCUINT8)&mcast1, (RTP_PFUINT8)&mask, (RTP_PFUINT8)0, RT_USEIFACEMETRIC, interfaceNumber, RT_INF)) { DEBUG_HANDLE_SOCKET_ERROR("Multicast xn_rt_add (recv)", FALSE); } if(SOCK_SOCKET_ERROR == xn_rt_add((RTP_PFCUINT8)&mcast2, (RTP_PFUINT8)&mask, (RTP_PFUINT8)0, RT_USEIFACEMETRIC, interfaceNumber, RT_INF)) { DEBUG_HANDLE_SOCKET_ERROR("Multicast xn_rt_add (send)", FALSE); } /* JRT - TBD call xn_ip_set_option */ default_mcast_iface = interfaceNumber; xn_interface_info(interfaceNumber, &info ); debug_printf( "ip address from interface info: %d.%d.%d.%d\r\n", (UINT32)info.my_ip_address[0], (UINT32)info.my_ip_address[1], (UINT32)info.my_ip_address[2], (UINT32)info.my_ip_address[3] ); debug_printf( "mac addrress from interface info: %x.%x.%x.%x.%x.%x\r\n", (UINT32)info.my_ethernet_address[0], (UINT32)info.my_ethernet_address[1], (UINT32)info.my_ethernet_address[2], (UINT32)info.my_ethernet_address[3], (UINT32)info.my_ethernet_address[4], (UINT32)info.my_ethernet_address[5] ); } } return TRUE; }