Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-26538

QUdpSocket: connectToHost() resets local port number specified by bind()

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: P2: Important P2: Important
    • 5.5.0 Alpha, 5.5.0
    • 4.7.4, 5.2.0
    • Network: Sockets
    • None
    • Debian Sid, amd64
    • 9fb68a90af79df3b8dc3225a3a97e2c6387afeec

      Consider the following code snippet (port numbers and ip address are arbitrary):

      #include<QtNetwork/QUdpSocket>
      #include<QCoreApplication>
      #include<QDebug>
      
      int main(int argc, char* argv[])
      {
          QCoreApplication(argc, argv);
      
          QUdpSocket s;
          s.bind(10000);
          qDebug() << "Local port before connectToHost()" << s.localPort();
      
          s.connectToHost(QHostAddress("87.250.251.3"), 20000);
          qDebug() << "Local port after connectToHost()" << s.localPort();
      
          s.write("ping!");
      
          return 0;
      }
      

      The output of the program is

      Local port before connectToHost() 10000
      Local port after connectToHost() 55154
      

      which means that local port binding made by bind() is undone by connectToHost(). tcpdump shows that indeed the udp packet is sent with randomly assigned source port. This behavior is not documented in the documentation for QUdpSocket and I consider it as a bug because it is not consistent with behavior of Berkley sockets. With Berkley sockets it is possible to bind() a udp socket first, then specify a default peer with connect(), then send data using send() or write(); connect() does not rebind a socket if it is already bound.

      POSIX specifically allows this behavior: «If the socket has not already been bound to a local address, connect() shall bind it to an address which, unless the socket's address family is AF_UNIX, is an unused local address.
      If the initiating socket is not connection-mode, then connect() shall set the socket's peer address, and no connection is made. For SOCK_DGRAM sockets, the peer address identifies where all datagrams are sent on subsequent send() functions, and limits the remote sender for subsequent recv() functions.» (extracted from description of connect() of POSIX-2008).

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            thiago Thiago Macieira
            mbalabin Mikhail Balabin
            Votes:
            5 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved:

                There are no open Gerrit changes