CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 2 FirstFirst 12
Results 16 to 23 of 23
  1. #16
    Join Date
    Sep 2003
    Posts
    280

    Re: Bind to a local port that is already in use

    I also make the first experiment on Ubuntu Linux. The result is the same as on Windows Vista. I just share this information.

  2. #17
    Join Date
    Jan 2008
    Posts
    20

    Re: Bind to a local port that is already in use

    Quote Originally Posted by Cooker
    I also make the first experiment on Ubuntu Linux. The result is the same as on Windows Vista. I just share this information.
    Are you willing to share the source code so I can try it myself on gentoo?

  3. #18
    Join Date
    Aug 2001
    Location
    Stockholm, Sweden
    Posts
    1,664

    Re: Bind to a local port that is already in use

    Well, it's only security issue if you do TCP bind to ANY address. If you bind to a specific address, no other TCP server can "steal" that specific address+port.

    Quote Originally Posted by MikeAThon
    Yes, it is a security issue, but it's not unique to Windows. The issue arises in all BSD socket implementations that support the SO_REUSEADDR option. AFAIK, all implementations do so, inclusive of Linux, Sun etc.

    Windows introduced the SO_EXCLUSIVEADDRUSE option to address this issue. See "Using SO_EXCLUSIVEADDRUSE" at http://msdn2.microsoft.com/en-us/library/ms740618.aspx . Here's a quote:

    I am not certain if other socket implementations (i.e., other than that on Windows) also have the SO_EXCLUSIVEADDRUSE option.

    Mike

  4. #19
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Bind to a local port that is already in use

    Quote Originally Posted by j0nas
    Well, it's only security issue if you do TCP bind to ANY address. If you bind to a specific address, no other TCP server can "steal" that specific address+port.
    I don't think I agree. The entire purpose of the SO_EXCLUSIVEADDR option is to prevent a malicious program from "stealing" the addr+port. Without SO_EXCLUSIVEADDR, it's my understanding that a malicious program can do exactly that:
    Quote Originally Posted by http://msdn2.microsoft.com/en-us/library/ms740618.aspx
    ... such reuse can be executed by malicious applications to disrupt the application
    .

  5. #20
    Join Date
    Jan 2008
    Posts
    20

    Re: Bind to a local port that is already in use

    Still waiting on that source code. I'm either doing something wrong or my OS has some security mechanism such as SO_EXCLUSIVEADDR at kernel level or something.

  6. #21
    Join Date
    Sep 2003
    Posts
    280

    Re: Bind to a local port that is already in use

    Quote Originally Posted by ludakot
    Are you willing to share the source code so I can try it myself on gentoo?
    At first, You can run the following source code on Windows OS.
    1. UDP Receiver
      Code:
      #include <stdio.h>
      #include <stdlib.h>
      
      #include <winsock2.h>              // for Winsock
      #pragma comment(lib,"Ws2_32.lib")  // for Winsock 
      
      void ErrExit(SOCKET fd, const char *format, ...);
      
      
      int main(int argc, char *argv[])
      {
      
      	WORD wVersionRequested = MAKEWORD(2, 2);
      	WSADATA wsaData;
      	int err = 0;
      	SOCKET sockfd = 0;
      	struct sockaddr_in local, remote;
      	int localport = 0;
      	int nrecvbytes = 0, fromlen = 0;
      	char recvbuf[128];
      	BOOL bOptVal = TRUE;
      	int bOptLen = sizeof(BOOL);
      
      	if (argc != 3) {
      		printf("Usage:\n");
      		printf("      program local_addr local_port\n");
      		printf("Description:\n");
      		printf("      Receive UDP packets from local_addr:local_port\n");
      		return -1;
      	} 
      	
      	localport = strtol(argv[2], NULL, 10);
      	
      	// Initiate use of the Winsock DLL
      	err = WSAStartup(wVersionRequested, &wsaData);
      	if (err != 0) {
      		// Could not find a usable WinSock DLL
      		printf("Couldn't find a usable WinSock DLL.\n");
      		return -1;
      	}
      
      	// Confirm that the WinSock DLL supports 2.2.              
      	if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2) 
      		ErrExit(0, "Bad winsock version.\n");
      
      	// Create a socket that is bound to a specific transport service provider
      	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      	if (sockfd == INVALID_SOCKET) 
      		ErrExit(0, "Can't open a socket with error code %d\n", WSAGetLastError());
      
      	// Contain information about local IP address and port
      	local.sin_family = AF_INET;         
          	local.sin_port = htons(localport);     
          	local.sin_addr.s_addr = inet_addr(argv[1]);
          	memset(local.sin_zero, '\0', sizeof local.sin_zero);
      
      	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
      		printf("Can't set SO_REUSEADDR option.\n");
      	}
      
      	// Associate a local address with a socket
          	err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
      	if (err == SOCKET_ERROR)
      		ErrExit(sockfd, "Can't bind to a local address and port with error code %d\n", WSAGetLastError());
      
      	memset(&remote, 0, sizeof remote);
      	memset(recvbuf, 0, sizeof recvbuf);
      
      	for (;;) 
      	{
      		fromlen = sizeof remote;
      		nrecvbytes = recvfrom(sockfd, recvbuf, sizeof recvbuf, 0, (struct sockaddr *)&remote, &fromlen);
      		
      		if (nrecvbytes == SOCKET_ERROR)
      			ErrExit(sockfd, "Can't receive messages with error code %d\n", WSAGetLastError());
      		
      		recvbuf[nrecvbytes] = '\0';
      		printf("Message [%s] from %s:%d\n", recvbuf, inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));		
      	}
      
      	return 0;
      }
      
      void ErrExit(SOCKET fd, const char *format, ...)
      {
      	va_list args;
      
      	va_start(args, format);
      	vfprintf(stderr, format, args);
      	va_end(args);
      
      	if (fd != NULL)
      		closesocket(fd);
      
      	WSACleanup();
      	exit(1);
      }
    2. UDP sender
      Code:
      #include <stdio.h>
      #include <stdlib.h>
      #include <conio.h>
      #include <time.h>
      
      #include <winsock2.h>              // for Winsock
      #pragma comment(lib,"Ws2_32.lib")  // for Winsock 
      
      void ErrExit(SOCKET fd, const char *format, ...);
      void wait(int seconds);
      
      int main(int argc, char *argv[])
      {
      
      	WORD wVersionRequested = MAKEWORD(2, 2);
      	WSADATA wsaData;
      	int err = 0;
      	SOCKET sockfd = 0;
      	struct sockaddr_in local, remote;
      	int localport = 0, remoteport = 0, cycle = 0;
      	int nsentbytes = 0;
      	BOOL bOptVal = TRUE;
      	int bOptLen = sizeof(BOOL);
      	
      
      	if (argc != 7) {
      		printf("Usage:\n");
      		printf("      program local_addr local_port cycle message remote_addr remote_port\n");
      		printf("Description:\n");
      		printf("      Send a UDP packet to remote_addr:remote_port from local_addr:local_port every cycle seconds\n");
      		return -1;
      	} 
      	
      	localport = strtol(argv[2], NULL, 10);
      	remoteport = strtol(argv[6], NULL, 10);
      	cycle = strtol(argv[3], NULL, 10);	
      	
      	// Initiate use of the Winsock DLL
      	err = WSAStartup(wVersionRequested, &wsaData);
      	if (err != 0) {
      		// Could not find a usable WinSock DLL
      		printf("Couldn't find a usable WinSock DLL.\n");
      		return -1;
      	}
      
      	// Confirm that the WinSock DLL supports 2.2.              
      	if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2) 
      		ErrExit(0, "Bad winsock version.\n");
      
      	// Create a socket that is bound to a specific transport service provider
      	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      	if (sockfd == INVALID_SOCKET) 
      		ErrExit(0, "Can't open a socket with error code %d\n", WSAGetLastError());
      
      	// Contain information about local IP address and port
      	local.sin_family = AF_INET;         
          	local.sin_port = htons(localport);     
          	local.sin_addr.s_addr = inet_addr(argv[1]);
          	memset(local.sin_zero, '\0', sizeof local.sin_zero);
      
      	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&bOptVal, bOptLen) == SOCKET_ERROR) {
      		printf("Can't set SO_REUSEADDR option.\n");
      	}
      
      	// Associate a local address with a socket
          	err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
      	if (err == SOCKET_ERROR)
      		ErrExit(sockfd, "Can't bind to a local address and port with error code %d\n", WSAGetLastError());
      
      	// Contain information about remote IP address and port
      	remote.sin_family = AF_INET;         
          	remote.sin_port = htons(remoteport);     
          	remote.sin_addr.s_addr = inet_addr(argv[5]);
          	memset(remote.sin_zero, '\0', sizeof remote.sin_zero);
      
      	printf("==> Press any key to quit the program. <==\n");
      	for (;;) 
      	{
      		if (kbhit())
      			break;
      		nsentbytes = sendto(sockfd, argv[4], strlen(argv[4]), 0, (struct sockaddr  *)&remote, sizeof remote);
      		if (nsentbytes == SOCKET_ERROR) 
      			ErrExit(sockfd, "Can't send meesages to remote address with error code%d\n", WSAGetLastError());
      		wait(cycle);
      	}
      
      	system("pause");
      	return 0;
      }
      
      void ErrExit(SOCKET fd, const char *format, ...)
      {
      	va_list args;
      
      	va_start(args, format);
      	vfprintf(stderr, format, args);
      	va_end(args);
      
      	if (fd != NULL)
      		closesocket(fd);
      
      	WSACleanup();
      	system("pause");
      	exit(1);
      }
      
      void wait(int seconds)
      {
      	clock_t endwait;
      	endwait = clock () + seconds * CLK_TCK ;
      	while (clock() < endwait) {}
      }

    The source code which runs on Ubuntu Linux isn't in my current PC. I will post later.

  7. #22
    Join Date
    Sep 2003
    Posts
    280

    Re: Bind to a local port that is already in use

    Quote Originally Posted by ludakot
    Still waiting on that source code. I'm either doing something wrong or my OS has some security mechanism such as SO_EXCLUSIVEADDR at kernel level or something.
    This SO_EXCLUSIVEADDR option is available on Microsoft Windows. On a Linux, all the socket information is in the man page for socket in section 7. You can type "man 7 socket" to get all these goodies and find if there exists SO_EXCLUSIVEADDRUSE option. That's my way.
    Last edited by Cooker; January 20th, 2008 at 06:38 AM.

  8. #23
    Join Date
    Sep 2003
    Posts
    280

    Re: Bind to a local port that is already in use

    Quote Originally Posted by ludakot
    Are you willing to share the source code so I can try it myself on gentoo?
    Linux version.
    The source code of UDP sender
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    
    #include <errno.h>
    #include <stdarg.h> 
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR   -1
    #define CLK_TCK        CLOCKS_PER_SEC
    
    void ErrExit(int fd, const char *format, ...);
    void wait(int seconds);
    
    int main(int argc, char *argv[])
    {
    
    	int err = 0;
    	int sockfd = 0;
    	struct sockaddr_in local, remote;
    	int localport = 0, remoteport = 0, cycle = 0;
    	int nsentbytes = 0;
    	int optval;
    	
    	if (argc != 7) {
    		printf("Usage:\n");
    		printf("      program local_addr local_port cycle message remote_addr remote_port\n");
    		printf("Description:\n");
    		printf("      Send a UDP packet to remote_addr:remote_port from local_addr:local_port every cycle seconds\n");
    		return -1;
    	} 
    	
    	localport = strtol(argv[2], NULL, 10);
    	remoteport = strtol(argv[6], NULL, 10);
    	cycle = strtol(argv[3], NULL, 10);	
    	
    	// Create a socket that is bound to a specific transport service provider
    	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    	if (sockfd == INVALID_SOCKET) 
    		ErrExit(0, "Can't open a socket with error %s\n", strerror(errno));
    
    	// Contain information about local IP address and port
    	local.sin_family = AF_INET;         
        	local.sin_port = htons(localport);     
        	local.sin_addr.s_addr = inet_addr(argv[1]);
        	memset(local.sin_zero, '\0', sizeof local.sin_zero);
    
    	optval = 1;
    	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof optval) == SOCKET_ERROR) {
    		printf("Can't set SO_REUSEADDR option.\n");
    	}
    
    	// Associate a local address with a socket
        	err = bind(sockfd, (struct sockaddr *)&local, sizeof local);
    	if (err == SOCKET_ERROR)
    		ErrExit(sockfd, "Can't bind to a local address and port with error %s\n", strerror(errno));
    
    	// Contain information about remote IP address and port
    	remote.sin_family = AF_INET;         
        	remote.sin_port = htons(remoteport);     
        	remote.sin_addr.s_addr = inet_addr(argv[5]);
        	memset(remote.sin_zero, '\0', sizeof remote.sin_zero);
    
    	for (;;) 
    	{
    		nsentbytes = sendto(sockfd, argv[4], strlen(argv[4]), 0, (struct sockaddr  *)&remote, sizeof remote);
    		if (nsentbytes == SOCKET_ERROR) 
    			ErrExit(sockfd, "Can't send meesages to remote address with error %s\n", strerror(errno));
    		wait(cycle);
    	}
    
    	return 0;
    }
    
    void ErrExit(int fd, const char *format, ...)
    {
    	va_list args;
    
    	va_start(args, format);
    	vfprintf(stderr, format, args);
    	va_end(args);
    
    	if (fd != NULL)
    		close(fd);
    	exit(1);
    }
    
    void wait(int seconds)
    {
    	clock_t endwait;
    	endwait = clock () + seconds * CLK_TCK ;
    	while (clock() < endwait) {}
    }
    I use 'tcpdump' to check UDP message at remote PC side.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured