[freetds] connect(2) for UDP

James K. Lowden jklowden at freetds.org
Thu Dec 18 18:40:43 EST 2008


Peter Deacon wrote:
> 
> UDP has no concept of connection.  Each message stands alone.
> 
> If the server binds to all interfaces and there are multiple interfaces 
> capable of reaching the client the source address of messages from the 
> server should be concidered random/determined by the routing system.

Not only are you right, you're right.  I even read as much after posting
my message.

And I found a server that answers on a different interface!  :-)  And,
using a combination of techniques, I seem to have something that works.  

1.  If I connect only, I miss answers from other interfaces.  
2.  If I bind only, I don't get ECONNREFUSED, only a timeout.  Perhaps
that's me or my implementation. 

Therefore, I do both, using two sockets, of course.  select(2) tells me
which one is ready, and, mirabile dictu, I get what I want: success,
timeout, or  ECONNREFUSED.  


== code ==
	fd_set fds;
	FD_ZERO(&fds);
	FD_SET(s1, &fds);
	FD_SET(s2, &fds);

	struct timeval timeout;
	bzero(&timeout, sizeof(timeout));
	timeout.tv_sec = 5;
	timeout.tv_usec = 0;
	
	cout << "reading from " << hostname << ":" << port << " ... " << flush;
	
	if( (erc = select(s2 + 1, &fds, NULL, NULL, &timeout)) == -1 ) {
		perror("select(2) failed");
		return 1;
	}

	if( 0 == erc ) {
		cerr << "timed out, sorry.\n";
		return 1;
	}
	
	cout << erc << " fd ready on " << flush;
	
	int s;
	char buffer[2048];
	
	if( FD_ISSET(s1, &fds) ) {
		s = s1;
		cout << "connected ... " << flush;
	}
	if( FD_ISSET(s2, &fds) ) {
		s = s2;
		cout << "bound ... " << flush;
	}
	
	while( (erc = read(s, &buffer, sizeof(buffer))) == -1 ) {
		perror("could not read");
		return 1;
	}

	cout << "done.  (read " << erc << " bytes)\n" << flush;

== edoc ==

Data arrive on the bound port.  Errors are detected on the connected port:


== output ==
$ ./connect_udp -h db03 -p 1434 
address of db03 is 10.10.10.10
binding local UDP socket ... done
sending  to  db03:1434 ... done.  (sent 1)
connecting UDP socket to db03:1434 ... done
writing  to  db03:1434 ... done.  (wrote 1)
reading from db03:1434 ... 1 fd ready on bound ... done.  (read 411 bytes)

./connect_udp -h localhost -p 1434
address of localhost is 127.0.0.1
binding local UDP socket ... done
sending  to  localhost:1434 ... done.  (sent 1)
connecting UDP socket to localhost:1434 ... done
writing  to  localhost:1434 ... done.  (wrote 1)
reading from localhost:1434 ... 1 fd ready on connected ...
 could not read: Connection refused
== tuptou ==

Too bad none of this is standardized.  Standards?  We don't need no
stinking standards!  

That about wraps up the research.  I think I'll file a bug report and see
if the project maintaner will update FreeTDS.  Oh, wait....

Regards, 

--jkl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: connect_udp.C
Type: application/octet-stream
Size: 4011 bytes
Desc: not available
Url : http://lists.ibiblio.org/pipermail/freetds/attachments/20081218/3cc66b30/attachment.obj 


More information about the FreeTDS mailing list