Bug in winNet.cc (DNS lookup failures...)
by Josh Goldshlag · in Torque Game Engine · 04/06/2002 (8:45 am) · 4 replies
I was just playing around with the TCPObject, and I found that if I try to connect to a host that doesn't exist, torque crashes. The crash is on line 122 of winNet.cc. It seems to be bauce if the DND fails, windows doesn't fill in the hostent.h_addr_list, and so that points to a portion of bad memory, causing an access violation.
Here is my fixed code:
Josh
Here is my fixed code:
if((*walk)->lookupHandle == handle)
{
NameLookup *temp = *walk;
struct hostent *hp = (struct hostent *) temp->hostEntStruct;
if(error)
{
notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
::closesocket(temp->socket);
}
else
{
SOCKADDR_IN ipAddr;
memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
ipAddr.sin_port = temp->port;
ipAddr.sin_family = AF_INET;
notifyEvent.tag = temp->socket;
bool wserr = ::connect(temp->socket, (PSOCKADDR) &ipAddr, sizeof(ipAddr)); // always errors out
if (wserr && WSAGetLastError() == WSAEWOULDBLOCK)
{
WSAAsyncSelect(temp->socket, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
}
}
Game->postEvent(notifyEvent);
*walk = temp->nextLookup;
delete temp;
break;
}Josh
#2
04/06/2002 (9:34 am)
Thanks Josh, just checked your fix into cvs. (I just fixed the DNS resolve problem).
#3
I want to add a word of caution to Josh' suggestion. Not only does this limit you to one client, but also one connection from that client (if he disconnects and recconects it will be under the old tag, so the addToTable call will make that fail). I'm currently attempting to find a solution which works for multiple clients and arbitrary connections. I guess I'll start off with this idea to spawn new TCPobjects for every connection reqest.
I'll post here when I get it working.
Ian
04/10/2008 (6:18 am)
Hey guys, I'm here to resurrect this six year old thread.I want to add a word of caution to Josh' suggestion. Not only does this limit you to one client, but also one connection from that client (if he disconnects and recconects it will be under the old tag, so the addToTable call will make that fail). I'm currently attempting to find a solution which works for multiple clients and arbitrary connections. I guess I'll start off with this idea to spawn new TCPobjects for every connection reqest.
I'll post here when I get it working.
Ian
#4
I was implementing the binary-over-tcp resource here:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6520
Don't make my mistake - for a listening TCPObject, in onConnectRequest you must spawn a new TCPObject using code something like this:
You can define the methods for your TCPObject as normal
And even if you have multiple connections it'll work as a new SimObject with the same name will not stop an old one calling methods.
Hope that helps...
Ian
04/10/2008 (6:42 am)
Ok, got it working.I was implementing the binary-over-tcp resource here:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6520
Don't make my mistake - for a listening TCPObject, in onConnectRequest you must spawn a new TCPObject using code something like this:
%c = new TCPObject(ListenDoCon, %id);
You can define the methods for your TCPObject as normal
function ListenDoCon::onLine(%this, %line)
And even if you have multiple connections it'll work as a new SimObject with the same name will not stop an old one calling methods.
Hope that helps...
Ian
Torque Owner Josh Goldshlag
If you try to have one TCPObject connect to another one (locally or remote), you get "Got bad connected receive event." every time you try to send data.
This is because when you do the accept on the listening socket, you get a new socket number. When you get data, it is under that new socket number, and the listener can not find the correct TCPObject. There isn't an easy solution to allow TCPObjects to get connected to by more than one client, but if you just want to support 1 client, add
addToTable(connectId);
to the end of TCPObject::onConnectionRequest (should be line 156 of tcpObject.cc.
The more correct solution would be to spawn a new TCPObject for each accpeted connection, or to allow object to be in the object table more than once.
I ran into this bug when I was trying to add some peer-peer stuff to Tribes 2 a bunch of months ago, it is so great to be able to fix this sort of thing now... :-)
Josh