FTP Question #3

Hi everyone,
I think I found a bug with the FTP utility that is included with tcpip 4.25 and 5.0. There is no timeout on the data connection which result of total freeze. Don’t get confuse with the FTP login. Data connection is when the server is trying to connect to your socket to send you data.

I’m just going to go over some stuff to bring uou up to speed

Ok so first
To eliminate the delay when the server down, I wrote my own ping function. If the connection is refused then the ping is ok.
Work pretty good and here is the code.


//****************************************************************
// Ping
//****************************************************************

int Ping (char *IpAddress)
	{
	static void SendTcpString_Timeout (int sig_number);
	timer_t tj;
	struct itimerspec 	TimerValue;
	struct sigevent 	event;
	static int 	sock= -1;
	struct sockaddr_in 	server;
	struct hostent *hp, *gethostbyname();

	if (sock < 0 )
		{
		/* Create socket */
		sock = socket(AF_INET, SOCK_STREAM, 0);
		if (sock < 0) 
			{
			perror("opening stream socket");
			exit(1);
			}

		/* Connect socket  using name specified by  command line.  */
		server.sin_family = AF_INET;
		hp = gethostbyname(IpAddress);
		if (hp == 0) 
			{
			fprintf(stderr, "%s: unknown host\n", IpAddress);
			exit(2);
			}
		memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
		server.sin_port = htons(1024);

		signal(SIGUSR1 , SendTcpString_Timeout);
		event.sigev_signo = SIGUSR1;
		tj = timer_create ( CLOCK_REALTIME, &event );
		if ( tj == -1 ) fprintf ( stderr, "Unable to attach timer\n");

		TimerValue.it_value.tv_sec = 50;
		TimerValue.it_value.tv_nsec = 0;
		TimerValue.it_interval.tv_sec = 0;
		TimerValue.it_interval.tv_nsec = 0;
		timer_settime( tj, TIMER_ABSTIME, &TimerValue, NULL );

		if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0) 
			{
			//perror("->Connecting stream socket");
			timer_delete (tj);
			close(sock);
			sock = -1;

			if (errno == EINTR) return (0);
			else return (1);
			}

		timer_delete (tj);
		close (sock);
		sock = -1;
		}

	return (1);
	}

//****************************************************************
// TcpSendString_TimeOut
//****************************************************************

static void SendTcpString_Timeout (int sig_number)
	{
	}

Then I wrote the following FTP script to check for update and to download file.

#!/bin/sh

SERVER=$1
PATH=$2
FTP_OPTION=$3
FILE=$4

LOCAL_PATH=/home/myftp
USER=ftp_user
PASSWD=ftp_user

# Delete old list
/bin/rm -f myftp.lst

case $FTP_OPTION in

GET_LIST) 

/usr/ucb/ftp -n $SERVER <<SCRIPT
user $USER $PASSWD
dir $PATH myftp.lst
quit
SCRIPT
;;

GET_FILE)

/usr/ucb/ftp -n $SERVER <<SCRIPT
user $USER $PASSWD
binary
cd $PATH
lcd download
get $FILE
quit
SCRIPT
;;

*)	;;
esac

There is also an aplication that ping the sever just before to launch the script. This application is launched at startup and everytime the device is rebooted then we are checking for update.

This is where my FTP nightmare begin. Sometime the FTP utility will freeze and it is totaly random. I added delay up to 10 sec thinking that the socket didn’t have time to initialize. Tried ftp 4.25 , 5.0 and the result was the same.

So I was browsing on QNX for clue and I found
quics.qnx.com/cgi-bin/dir_find.c … tcpip/ftp/
An FTP library wrote by Oleg Orel.

So I wrote an apllication using the library and guess what? I was experiencing the same issue , program freeze !!!

Apparently to receive data from the server you have to establish a data connection by opening a port using a socket and I found exactly what was the problem.The program was waiting to accept a connection from the server to receive the data but for some reason the server didn’t try to connect.

So I added the following code to FtpData.c

FD_ZERO(&ready);
   	FD_SET(NewSocket, &ready);
   	to.tv_sec = 5;
   	to.tv_usec = 0;

   	if (select(NewSocket + 1, &ready, 0, 0, &to) < 0) 
		{
       	perror("select");
   	    return -1;
    	}

	if (FD_ISSET(NewSocket, &ready))
		{
		if (( Accepted_Socket = accept (NewSocket , &from , &fromlen )) < 0)
    		{
			close(NewSocket);
			return -1;
			}
		}
	else
		{
		printf("Timeout 5 sec - Exit FtpData \n");
		return -1;
		}

If the timeout expired then I launched the function again until it failed 3 times.

It’s worked but It is really random since u can failed up to 3 time (rarely but it happened).

This is really slowing down the boot up of my system and we would like to know if anybody got any insight about why the server is not trying to connect sometime.

Server is running
Micorsoft FTP Service (Version 5.0)

It doesn’t happen when u start the application manually or with the FTp utility. So even if i add a delay of 15 sec when I tried to launch application at startup the server will randomly not connect to my data connection.

If anybody is an FTP expert and could give me some hint about this behavior that will be really appreciated.

Johnny

Johnny,

I see your using getHostByName()

If the DNS server (which is not you and may not be the Windows box you want to ftp from) is not there or not responding, your socket commands will hang a LONG time waiting to timeout on the DNS lookup.

Try disabling your DNS server stuff in QNX (In QNX6 it is in a file called net.cfg) and instead specify the Windows IP address manually and see if the problem goes away. If it does, it means it’s a DNS lookup issue and not an FTP one.

For example if I enable a DNS server with a bogus IP address and do a ‘ping’ to a valid node (even on the same subset) the initial ping will hang for 45 seconds before starting to return the ping result. That’s because of the DNS failure. If I then disable the DNS server my ping responds instantly.

Tim

Tim,
I’m using QNX4 and I don’t think DNS is enable. I don’t have any problem pingning any address on the network. My reel issue is when I start using FTP. Sometime when I open a data connection to receive a file or to simply looked at a directory the FTP is freezing. The reason is because we are waiting to accept a connection from the server to receive data and the sever doesn’t try to connect.

I’m not sure why but it is totatly random and the work around that i have now is to use Oleg’s library.
I’m still thinking there is a flaw with the FTP utility provide with tcpip 5.0. Everything should have a timeout.

The other issues that have now is my application is very slow to start because of this FTP boggus.
I’m using only static IP address in QNX and this is my (netstart/tcpip.node)


#! /bin/ksh

export SOCK=$NODE
/bin/slay -f Tcpip;
/usr/ucb/Tcpip node$NODE &

# Note:  assuming ethernet interface on logical LAN 1
/usr/ucb/ifconfig lo0 localhost up
/usr/ucb/ifconfig en1 node$NODE up netmask 255.255.0.0

# Note:  to act as a TCP/IP server, uncomment the next line
/usr/ucb/inetd

Johnny,

You can tell if DNS is enabled by doing:

ping www.espn.com

If DNS is enabled, www.espn.com will be resolved into an IP address. If it’s not, then you’ll get an immediate error message indicating no DNS lookup possible.

It also sounds like the Windows server has a problem with its ftp client. I wonder if some kind of firewall issues are the culprit. It’s too bad you have to use a Windows server for the updates. It would be a lot better if you could use a QNX or Linux box for that function. At this point your probably at the mercy of the Windows machine in terms of how slow you start up and nothing you can do on your end is going to fix a problem on the other end. Assuming you have some control over the Windows server, you might consider trying to install a different ftp client on it (I know the default Windows FTP client leaves a LOT to be desired).

Tim

Tim,
DNS is not enable.

The FTP connection is inside our firewall and i don’t think that the problem. I noticed that if I’m using ftp manually then i’m not getting that freezing issue with the data connection.

Johnny,

It’s very strange that if you do it manually it always works without the delay.

How soon after starting inetd are you trying to connect and do the ftp to the server? I wonder if inetd isn’t finished initializing sometimes and so your not in a position to receive the connect from the server.

You can check this if you have an ethernet sniffer. A really quick way is to install ‘ethereal’ (a free download) on the Windows server. Then start it and sniff for packets going/coming from your QNX machine. Boot up your QNX machine and capture the packets for a good case (where everything works fine without timeouts) and a bad case (where there are timeouts). Then compare the packets and see if indeed Windows is not connecting or if QNX isn’t getting the connection.

Tim

Tim,
In a bad or good situation the FTP login is always sucessfull. When the FTP freeze is because QNX is waiting for windows to connect to the socket to send data. In short the program block with the accept function.I add a delay up to 15 sec between inetd and and the FTP applications and it is always random. Sometime it work on the 1st time and sometime can take up 5 time. I add a 5 sec timer to the accept function. If timeout expired then I restart the connection. I found really stange that if i start the same program mannualy trought a console it always works. When I start the application automaticly I’m using the on command to start a new process into a console.

on -t /dev/con2 Myftp

I guess I’m going to try your sniffer utility to see if i can get more clue.