views:

392

answers:

2

I've got this code in my socket class:

bool GSocket::Listen(int Port)
{
 d->Socket = socket(AF_INET, SOCK_STREAM, 0);
 if (d->Socket >= 0)
 {
  sockaddr Addr;
  sockaddr_in *a = (sockaddr_in*) &Addr;
  ZeroObj(Addr);
  a->sin_family = AF_INET;
  a->sin_port = htons(Port);
  a->sin_addr.OsAddr = INADDR_ANY;

  if (bind(d->Socket, &Addr, sizeof(Addr)) >= 0)
  {
   if (listen(d->Socket, SOMAXCONN) != SOCKET_ERROR)
   {
    return true;
   }
   else
   {
    Error();
   }
  }
  else
  {
   Error();
  }
 }
 else
 {
  Error();
 }

 return false;
}

The "Error()" method just calls WSAGetLastError and passes the error and it's description up to the app. Anyway it works fine on my machine (xp sp2) but fails on my friends xp sp3 machine. In particular the bind call fails and WSAGetLastError returns "2", which isn't even a valid socket error code. The value of "Port" passed in is 80, I'm running a simple HTTP server as UI for a service. I'm not entirely sure why I check for >= 0, but it could be related to non-windows platforms I also use this code on. In any case according to the MSDN the return code on error for bind is SOCKET_ERROR which is -1 so that check should be ok.

Have I missed something simple?

Update: We just tried a different port number '8888' and everything works as expected. So it seems that the low port number is the issue. There is nothing actively listening on that port before we run my service, so I'm thinking that it's some sort of new permissions issue in SP3 that stops processes listening on ports < 1024 unless they have certain permissions, similar to the linux/unix way of doing things. Still I'd like to be able to sort it out anyway.

A: 

You're doing funny pointer arithmetic there... just put a sockaddr_in on the stack, and pass a pointer to it to bind.

sockaddr_in a = {0};
a.sin_family = AF_INET;
a.sin_port = htons(Port);
a.sin_addr.OsAddr = INADDR_ANY;

if (bind(d->Socket, (sockaddr *) &a, sizeof(a)) >= 0)

Also, try to check if privileges are getting in the way. Is there something open already on that port (ask netstat)

Thanatos
Nothing is using the port already (we used tcpview) and I think perms are the problem, but how to "get" the rights perms to open the socket? Thats the nut of the question.
fret
+1  A: 

Port numbers in the range from 0 through 1023 are well known ports and the operating system can require administrative privileges in order to bind to them. Consequently, any application that attempts to use these ports must be privileged.

Steve Emmerson
This is just extra information. What I need to know is HOW do I get those permissions?
fret
For UNIX, the program must be owned by root and setuid (i.e., have the set-UID bit turned on).I don't know about Windows.
Steve Emmerson