]> sjero.net Git - iperf/blobdiff - src/Listener.cpp
DCCP support for iperf
[iperf] / src / Listener.cpp
index cf3c1596c790cbd03c659e7ca19ff3c7ca4585ea..1cc0de944c232a316954cf712e78c36e95f2693b 100644 (file)
@@ -114,28 +114,26 @@ Listener::~Listener() {
 /* ------------------------------------------------------------------- 
  * Listens for connections and starts Servers to handle data. 
  * For TCP, each accepted connection spawns a Server thread. 
- * For UDP, handle all data in this thread for Win32 Only, otherwise
- *          spawn a new Server thread. 
+ * For datagram-oriented protocols, spawn a new Server thread.
  * ------------------------------------------------------------------- */ 
-void Listener::Run( void ) {
+void Listener::Run(void)
+{
 #ifdef sun
-    if ( ( isUDP( mSettings ) && 
-           isMulticast( mSettings ) && 
-           !isSingleUDP( mSettings ) ) ||
-         isSingleUDP( mSettings ) ) {
+    if ( ( isPacketOriented( mSettings ) &&
+           isMulticast( mSettings )      &&
+          !isSingleUDP( mSettings )    ) || isSingleUDP( mSettings ) ) {
         UDPSingleServer();
-    } else
 #else
     if ( isSingleUDP( mSettings ) ) {
         UDPSingleServer();
-    } else
 #endif
-    {
-        bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
+    } else {
+        bool client = false,
+             mCount = (mSettings->mThreads != 0);
         thread_Settings *tempSettings = NULL;
         Iperf_ListEntry *exist, *listtemp;
-        client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) : 
-                                  (client_hdr*) mBuf);
+        client_hdr* hdr;
+
         
         if ( mSettings->mHost != NULL ) {
             client = true;
@@ -179,7 +177,7 @@ void Listener::Run( void ) {
                                               (sockaddr*) &server->peer ) ) {
                     // Not allowed try again
                     close( server->mSock );
-                    if ( isUDP( mSettings ) ) {
+                    if ( isConnectionLess( mSettings ) ) {
                         mSettings->mSock = -1;
                         Listen();
                     }
@@ -215,19 +213,19 @@ void Listener::Run( void ) {
     
             tempSettings = NULL;
             if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
-                if ( !UDP ) {
-                    // TCP does not have the info yet
+                if ( !isConnectionLess(mSettings)) {
+                    hdr = (client_hdr*) mBuf;
+
+                    // TCP/DCCP does not have the info yet
                     if ( recv( server->mSock, (char*)hdr, sizeof(client_hdr), 0) > 0 ) {
-                        Settings_GenerateClientSettings( server, &tempSettings, 
-                                                          hdr );
+                        Settings_GenerateClientSettings( server, &tempSettings, hdr );
                     }
                 } else {
-                    Settings_GenerateClientSettings( server, &tempSettings, 
-                                                      hdr );
+                    hdr = (client_hdr *) ( ((dgram_record*)mBuf) + 1 );
+                    Settings_GenerateClientSettings( server, &tempSettings, hdr );
                 }
             }
     
-    
             if ( tempSettings != NULL ) {
                 client_init( tempSettings );
                 if ( tempSettings->mMode == kTest_DualTest ) {
@@ -245,7 +243,7 @@ void Listener::Run( void ) {
             thread_start( server );
     
             // create a new socket
-            if ( UDP ) {
+            if ( isConnectionLess( mSettings ) ) {
                 mSettings->mSock = -1; 
                 Listen( );
             }
@@ -264,44 +262,32 @@ void Listener::Run( void ) {
 
 /* -------------------------------------------------------------------
  * Setup a socket listening on a port.
- * For TCP, this calls bind() and listen().
- * For UDP, this just calls bind().
+ * For connection-oriented protocols, this calls bind() and listen().
+ * For connection-less protocols, this just calls bind().
  * If inLocalhost is not null, bind to that address rather than the
  * wildcard server address, specifying what incoming interface to
  * accept connections on.
  * ------------------------------------------------------------------- */
-void Listener::Listen( ) {
+void Listener::Listen()
+{
     int rc;
+    int boolean = 1;
+    Socklen_t len = sizeof(boolean);
 
     SockAddr_localAddr( mSettings );
-
-    // create an internet TCP socket
-    int type = (isUDP( mSettings )  ?  SOCK_DGRAM  :  SOCK_STREAM);
-    int domain = (SockAddr_isIPv6( &mSettings->local ) ? 
-#ifdef HAVE_IPV6
-                  AF_INET6
-#else
-                  AF_INET
-#endif
-                  : AF_INET);
-
-    mSettings->mSock = socket( domain, type, 0 );
-    WARN_errno( mSettings->mSock == INVALID_SOCKET, "socket" );
+    MakeSocket( mSettings );
 
     SetSocketOptions( mSettings );
 
     // reuse the address, so we can run if a former server was killed off
-    int boolean = 1;
-    Socklen_t len = sizeof(boolean);
     setsockopt( mSettings->mSock, SOL_SOCKET, SO_REUSEADDR, (char*) &boolean, len );
 
-    // bind socket to server address
+    // listen for connections (TCP/DCCP only).
     rc = bind( mSettings->mSock, (sockaddr*) &mSettings->local, mSettings->size_local );
     WARN_errno( rc == SOCKET_ERROR, "bind" );
 
-    // listen for connections (TCP only).
     // default backlog traditionally 5
-    if ( !isUDP( mSettings ) ) {
+    if ( !isConnectionLess( mSettings ) ) {
         rc = listen( mSettings->mSock, 5 );
         WARN_errno( rc == SOCKET_ERROR, "listen" );
     }
@@ -375,17 +361,19 @@ void Listener::McastSetTTL( int val ) {
  * until a new connection arrives.
  * ------------------------------------------------------------------- */
 
-void Listener::Accept( thread_Settings *server ) {
-
+void Listener::Accept( thread_Settings *server )
+{
     server->size_peer = sizeof(iperf_sockaddr); 
-    if ( isUDP( server ) ) {
+
+    if ( isConnectionLess( server ) ) {
         /* ------------------------------------------------------------------- 
-         * Do the equivalent of an accept() call for UDP sockets. This waits 
-         * on a listening UDP socket until we get a datagram. 
+         * Do the equivalent of an accept() call for connection-less sockets.
+         * This waits on a listening datagram socket until we get a datagram.
          * ------------------------------------------------------------------- */
         int rc;
         Iperf_ListEntry *exist;
         int32_t datagramID;
+
         server->mSock = INVALID_SOCKET;
         while ( server->mSock == INVALID_SOCKET ) {
             rc = recvfrom( mSettings->mSock, mBuf, mSettings->mBufLen, 0, 
@@ -394,14 +382,14 @@ void Listener::Accept( thread_Settings *server ) {
 
             Mutex_Lock( &clients_mutex );
     
-            // Handle connection for UDP sockets.
+            // Handle connection for datagram-based sockets.
             exist = Iperf_present( &server->peer, clients);
-            datagramID = ntohl( ((UDP_datagram*) mBuf)->id ); 
+            datagramID = ntohl( ((dgram_record*) mBuf)->id );
             if ( exist == NULL && datagramID >= 0 ) {
                 server->mSock = mSettings->mSock;
                 int rc = connect( server->mSock, (struct sockaddr*) &server->peer,
                                   server->size_peer );
-                FAIL_errno( rc == SOCKET_ERROR, "connect UDP", mSettings );
+                FAIL_errno( rc == SOCKET_ERROR, "datagram-based connect", mSettings );
             } else {
                 server->mSock = INVALID_SOCKET;
             }
@@ -427,15 +415,17 @@ void Listener::Accept( thread_Settings *server ) {
 
 void Listener::UDPSingleServer( ) {
     
-    bool client = false, UDP = isUDP( mSettings ), mCount = (mSettings->mThreads != 0);
+    bool client = false, mCount = (mSettings->mThreads != 0);
     thread_Settings *tempSettings = NULL;
     Iperf_ListEntry *exist, *listtemp;
     int rc;
     int32_t datagramID;
-    client_hdr* hdr = ( UDP ? (client_hdr*) (((UDP_datagram*)mBuf) + 1) : 
-                              (client_hdr*) mBuf);
     ReportStruct *reportstruct = new ReportStruct;
+    dgram_record *dgram_hdr = (dgram_record *)mBuf;
     
+
+    assert( isPacketOriented( mSettings ) );
+
     if ( mSettings->mHost != NULL ) {
         client = true;
         SockAddr_remoteAddr( mSettings );
@@ -461,15 +451,15 @@ void Listener::UDPSingleServer( ) {
             }
         
         
-            // Handle connection for UDP sockets.
+            // Handle connection for datagram-based sockets.
             exist = Iperf_present( &server->peer, clients);
-            datagramID = ntohl( ((UDP_datagram*) mBuf)->id ); 
+            datagramID = ntohl( dgram_hdr->id );
             if ( datagramID >= 0 ) {
                 if ( exist != NULL ) {
                     // read the datagram ID and sentTime out of the buffer 
                     reportstruct->packetID = datagramID; 
-                    reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec  );
-                    reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec ); 
+                    reportstruct->sentTime.tv_sec = ntohl( dgram_hdr->tv_sec  );
+                    reportstruct->sentTime.tv_usec = ntohl( dgram_hdr->tv_usec );
         
                     reportstruct->packetLen = rc;
                     gettimeofday( &(reportstruct->packetTime), NULL );
@@ -489,8 +479,8 @@ void Listener::UDPSingleServer( ) {
                 if ( exist != NULL ) {
                     // read the datagram ID and sentTime out of the buffer 
                     reportstruct->packetID = -datagramID; 
-                    reportstruct->sentTime.tv_sec = ntohl( ((UDP_datagram*) mBuf)->tv_sec  );
-                    reportstruct->sentTime.tv_usec = ntohl( ((UDP_datagram*) mBuf)->tv_usec ); 
+                    reportstruct->sentTime.tv_sec = ntohl( dgram_hdr->tv_sec  );
+                    reportstruct->sentTime.tv_usec = ntohl( dgram_hdr->tv_usec );
         
                     reportstruct->packetLen = rc;
                     gettimeofday( &(reportstruct->packetTime), NULL );
@@ -500,14 +490,9 @@ void Listener::UDPSingleServer( ) {
                     gettimeofday( &(reportstruct->packetTime), NULL );
                     CloseReport( exist->server->reporthdr, reportstruct );
         
-                    if ( rc > (int) ( sizeof( UDP_datagram )
-                                                      + sizeof( server_hdr ) ) ) {
-                        UDP_datagram *UDP_Hdr;
-                        server_hdr *hdr;
-        
-                        UDP_Hdr = (UDP_datagram*) mBuf;
+                    if ( rc > (int)(sizeof(dgram_record) + sizeof(server_hdr)) ) {
+                        server_hdr *hdr = (server_hdr *)(dgram_hdr + 1);
                         Transfer_Info *stats = GetReport( exist->server->reporthdr );
-                        hdr = (server_hdr*) (UDP_Hdr+1);
         
                         hdr->flags        = htonl( HEADER_VERSION1 );
                         hdr->total_len1   = htonl( (long) (stats->TotalLen >> 32) );
@@ -526,13 +511,9 @@ void Listener::UDPSingleServer( ) {
                     EndReport( exist->server->reporthdr );
                     exist->server->reporthdr = NULL;
                     Iperf_delete( &(exist->server->peer), &clients );
-                } else if ( rc > (int) ( sizeof( UDP_datagram )
-                                                  + sizeof( server_hdr ) ) ) {
-                    UDP_datagram *UDP_Hdr;
-                    server_hdr *hdr;
-        
-                    UDP_Hdr = (UDP_datagram*) mBuf;
-                    hdr = (server_hdr*) (UDP_Hdr+1);
+
+                } else if ( rc > (int)(sizeof(dgram_record) + sizeof(server_hdr)) ) {
+                    server_hdr *hdr = (server_hdr *) (dgram_hdr + 1);
                     hdr->flags = htonl( 0 );
                 }
                 sendto( mSettings->mSock, mBuf, mSettings->mBufLen, 0,
@@ -601,8 +582,9 @@ void Listener::UDPSingleServer( ) {
 
         tempSettings = NULL;
         if ( !isCompat( mSettings ) && !isMulticast( mSettings ) ) {
-            Settings_GenerateClientSettings( server, &tempSettings, 
-                                              hdr );
+            client_hdr* hdr = (client_hdr *)(dgram_hdr + 1);
+
+            Settings_GenerateClientSettings(server, &tempSettings, hdr);
         }