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;
}