redirecting qconn

I have a qnx box behind a firewall that I would like to connect to through qconn. I would like write a client software which accepts connection on 443 and redirects it to port 8000. I have done similar thing with phrelay and it didn’t have any problem, but it doesn’t seem to work for qconn.

I notice that qconn setup 2 or 3 connections when connected to IDE, is this part of the complication?

Any idea as to how this can be done?
Thanks

It depends on what you are trying to make work. The main qconn service is sitting on port 8000 (by default) but when clients connect to it for some services, it will potentially re-direct them to alternative ports. An example of this is the debugger (pdebug). The main system information services should work however. Are you creating the target in the IDE connecting to the 443 port?

Yes I am, and I want qconn to listen on 8000. I know I can run qconn with “qconn port=443” but this is not what I want. I have a server much like inetd, who listens on port 443 and will redirect traffic to the corresponding services like (phrelay, qconn). but when I redirect the traffic to qconn (8000), qconn tries communicate and creates 2 or 3 more ports but I can’t get it work beyond that.

I think I might have to direct traffic to this newly created alternative ports but how would I know their port number if it’s kind of random ? I don’t know I am kind of lost on how qconn communicates?

I think I might have to explain what I am trying to do here in more detail.

I have a my service program (similar to inetd) which listens on port 443. This service program also tries to connect to qconn as soon as it starts up on port 8000, but does not read or write on that port until IDE on the other end tries to connect on 443. Onces the IDE connects on 443, the service program just monitors 443 and 8000 and redirects data so that IDE and qconn can communicate. What would be the best way in accomplishing this?

Here is my simple program that tries to do this. It’s just single threaded and I just wanted to get the qconn communication to work first. As you can see this will not accept one connection for now.

int IDE_sock,qconn_sock,n;
struct sockaddr_in IDE_server, qconn_server;
struct sockaddr_in IDE_addr;
fd_set IDE_ready;
char buf[1043],buf2[1043];
struct timeval to;
int length;
int opt_value=1;
int bufsize1=1043;
int bufsize2=1043;
int i=0,j=0;

int sendall(int s, char *buf, int *len)
{
int total = 0; // how many bytes we’ve sent
int bytesleft = *len; // how many we have left to send
int n=0;

while(total < *len) {
    n = send(s, buf+total, bytesleft, 0);
    if (n == -1) { break; }
    total += n;
    bytesleft -= n;
}

*len = total; // return number actually sent here

return n==-1?-1:0; // return -1 on failure, 0 on success

}

int recvtimeout(int s, char *buf, int len, int timeout)
{
fd_set fds;
int n,rx,tmp;
struct timeval tv;
rx=0;
tmp=0;
// set up the file descriptor set
FD_ZERO(&fds);
FD_SET(s, &fds);

// set up the struct timeval for the timeout
tv.tv_sec =  0;//0;//timeout;
tv.tv_usec =timeout;//timeout;

// wait until timeout or data received
n = select(s+1, &fds, NULL, NULL, &tv);
if (n == 0) return -2; // timeout!
if (n == -1) return -1; // error

// data must be here, so do a normal recv()
return recv(s, buf, len, 0);

}

int read_qconn(int _sock)
{
n=recvtimeout(qconn_sock,buf2,bufsize2,1);//coming from phrelay
if (n == -1)
{
// error occurred
printf(“on qconn\n”);
perror(“recvtimeout”);
return 0;
}
else if (n == -2)
{
// timeout occurred
}
else if (n==0)
{
printf(“connected closed from qconn\n”);
close(qconn_sock);
return 0;
}
else
{
// got some data in buf
printf(“qconn rx=%d\n”,n);
if (sendall(_sock, buf2,&n) == -1)
{
perror(“sendall while trying to send to IDE”);
printf(“We only sent %d bytes because of the error!\n”, n);
return 0;
}
}
return 1;
}

int read_IDE(int _sock)
{
n=recvtimeout(_sock,buf,bufsize1,1); //coming from phindows
if (n == -1)
{
// error occurred
printf(“on IDE_sock\n”);
perror(“recvtimeout”);
return 0;
}
else if (n == -2)
{
// timeout occurred
}
else if (n==0)
{
printf(“connected closed from IDE server\n”);
close(_sock);
return 0;

}
else 
{
	// got some data in buf
	printf("IDE rx=%d\n",n);
	if (sendall(qconn_sock, buf,&n) == -1) 
	{
		perror("sendall while trying to send to qconn");
		printf("We only sent %d bytes because of the error!\n",n);
		return 0;
	} 
}
return 1;

}

int main(int argc, char *argv[]) {
int _sock;

signal(SIGPIPE,SIG_IGN);
//create socket
IDE_sock=socket(AF_INET,SOCK_STREAM,0);
qconn_sock=socket(AF_INET,SOCK_STREAM,0);
	
setsockopt(IDE_sock,IPPROTO_TCP,TCP_NODELAY,&opt_value,sizeof(opt_value));
setsockopt(qconn_sock,IPPROTO_TCP,TCP_NODELAY,&opt_value,sizeof(opt_value));
	
if(IDE_sock<0 || qconn_sock<0)
{
	perror("opening stream socket");
	exit(1);
}

IDE_server.sin_family=AF_INET;
IDE_server.sin_addr.s_addr=INADDR_ANY;
IDE_server.sin_port=htons(443);
	
if(bind(IDE_sock,(struct sockaddr *)&IDE_server,sizeof(IDE_server)))
{
	shutdown (IDE_sock,SHUT_RDWR);
	perror("binding stream socket");
	exit(1);
}
//setup a socket connection to local phindow phrelay session
qconn_server.sin_family=AF_INET;
qconn_server.sin_addr.s_addr=INADDR_ANY;
qconn_server.sin_port=htons(8000);

listen(IDE_sock,3);
FD_ZERO(&IDE_ready);
//FD_ZERO(&qconn_ready);
while(1)
{
	FD_SET(IDE_sock,&IDE_ready);
	to.tv_sec=0;
	to.tv_usec=1;
		
	//if(select(IDE_sock+1,&IDE_ready,&IDE_ready,0,&to)<0)
	if(select(IDE_sock+1,&IDE_ready,&IDE_ready,NULL,&to)<0)
	{
		perror("select");
		return EXIT_FAILURE;
	}
		
	if (FD_ISSET(IDE_sock,&IDE_ready))
	{
		printf("IDE connected\n");
		length=sizeof(IDE_addr);
		_sock=accept(IDE_sock,(struct sockaddr *)&IDE_addr,(int *)&length);
		if(_sock==-1)
		{
			perror("sock accept");
			return EXIT_FAILURE;
		}
		
		printf("connecting to qconn 8000");
		if(connect(qconn_sock,(struct sockaddr *)&qconn_server,sizeof(qconn_server)) <0)
		{
			perror("connecting stream qconn server socket");
			close(qconn_sock);
			exit(1);
		}
		while(1)
		{
			read_qconn(_sock);
			read_IDE(_sock);
		}
	}
}
close(IDE_sock);
close(_sock);
return 0;

}

I think there should be something like netstat, with this you could check what ports qconn opened (may works over sysctl or ioctl, at least it has a lot of options for sockets, or another control ^^).
Then you just would have to check what request opended what port and again just redirect the data.

  1. You only need to connect to qconn, if someone connect to port 443, so why bother monitoring is qconn come up or not.
  2. You want to do select() in the loop to find which socket (qconn or ide) is readable, read from that socket, write it into
    another one, … (instead of use receivetimeout to pulling it)

I don’t like using netstat to get information about what ports are opened, it just doesn’t seem clean. And how would I find out which ports are opened for what. I guess I could just do some trial and error…
Also Xtang, I don’t understand what you mean by 1), I mensioned that I use 443 for accepting other connection like phindows, so I need to know if some one tries to connect to 443, what connection that is. Also I do use select in the “receivetimeout” and it is not polling if that’s what you mean? And I think I am checking if the ports (IDE or qconn) are readable and redirecting to another, but for qconn it doesn’t seem to be as simple as that because it opens 1 or 2 other ports depending on the IDE request (like debug, profiling, target filesystem etc…).

I meant you don’t need to connect to qconn if nobody connect to you.
Also, if no activate on the link, select() will block forever. So:

   listen_on_port (443);
   sockIDE=accept(...);
   // somebody connect to port 443, let's connect to qconn
   sockqconn=connect(8000);

   // now passing arround the date between the 2 socket
   while (1) {
      FD_SET(sockqconn, sockIDE);
      select(the_fd_set,...);
      if (sockqconn is readable) {
          read(sockqconn, buf ...);
          write(sockIDE, buf ...);
      } else if (sockIDE is readable) {
          read(sockIDE, buf ...);
          write(sockqconn, buf...);
      }
  }

I am not connecting to qconn until someone connects to 443, and select is not block forever because I set up a timeout of 1usec (look at my recvtimeout() code)
can anyone write a very simple port forwarding code here? Is my code not doing that?

Jinma,

I downloaded and looked at your code. It’s certainly not the way I would do it for simple port forwarding.

At this link is a very simple port forwarding program that I know works

beej.us/guide/bgnet/output/html/ … tml#select

Go about 1/3 down on the page to the ‘cheesy multi person chat server’ sample code. This is what you want using select.

The only thing you need to change is that when incoming data arrives on one socket you don’t echo it to all clients like a chat window does but rather just forward it to the other end.

You’ll also have to add code to connect to qconn when someone connects on 443 (in the handle new connects part of the code). Just remember to add that connection to qconn to the fd set.

Tim

thanks i’ll give it a try.