Friday, March 23, 2012

How to write FTP Application

To Write FTP application, you will need to write the ftp server and the ftp client. The following illustrates the concepts for writing an FTP Server. In the following post, I will include the ftp client code.


Here’s a simple code for an ftp server that uses UDP socket:

Step 1:  Define connection port number and create socket to listen on port number

int main()
{
   extern connection connS;
   char buffer[MAX_SRTP_PACKET+10]="";
   extern incoming_buff server_buff[25];
  
   int process_id, recSome, sz, cls, counter=0;
   srtp_header srtp;
  
   connS.currentState = CLOSED;
   printf("Enter Port Number: ");
   scanf("%d",&connS.portNumber);

Step 2: Initialize buffer for incoming client messages

initializeBuff();
     
   while (connS.currentState != LISTEN)  
     connS.connection_number = SRTP_Listen(connS.portNumber);
  
   if (connS.currentState == LISTEN)
      sz = sizeof(connS.host_addr);    

Step 3: Set up handlers for signals and interrupts

struct sigaction act;
   act.sa_handler = sig_chld;
   sigemptyset(&act.sa_mask);
   act.sa_flags = SA_NOCLDSTOP;
  
   if (sigaction(SIGCHLD,&act,NULL)<0)
   {
     printf("CHILD SIGNAL ERROR\n");
     return 1;
   }     

Step 4: Implement server state machine inside infinite loop – server maintains state based on client response and messages to follow TCP state change behavior (ie – this in turn makes UDP “behave” like TCP with SRTP layer api)

    for (;;)
      {  
         recSome = recvfrom(connS.socketDesc, buffer, MAX_SRTP_PACKET+10,0,(struct sockaddr *)&connS.host_addr, &sz);
                 
                     if (recSome == -1)
                                 {
                                 }            
                     else if (buffer != NULL)
                                 {                
                       srtp = parser(buffer);
                       if (connS.currentState == LISTEN)
                                   {
                         if ( strcmp(srtp.contrl_field, SYN) == 0)
                                                 {
                           connS.currentState = SYN_RECVD;
                           printf("*****SYN RECEIVED!!!!!!!!\n");
                           synR = synTO= 0;          
                           int temp = SRTP_Listen(connS.portNumber);
                                                 }
                                   }
                       else if (connS.currentState == SYN_RECVD)
                                   {
                         if (strcmp(srtp.contrl_field, ACK) == 0)
                                                 {
                           printf("SYN ACK RECD!!\n");
                           connS.currentState=ESTABLISHED;
                           printf("CONNECTION ESTBLISHED!\n");                    
                                                 }                   
                                   }
                       else if (connS.currentState == ESTABLISHED)
                                   {
                         printf("currentState ESTABLISHED!!\n");
                         if (((strcmp(srtp.contrl_field, DAT)) == 0) || (strcmp(srtp.contrl_field, DATL) == 0))
                                                 {  
                                                   printf("RECEIVING DATA PACKETS!!\n");
                                       if (checksum(srtp)==srtp.cksum)
                                                   {
                                         int inBuff=bufferPacket(srtp);
                                         printf("In buff: %d\n", inBuff);
                                         if (inBuff==-1)
                                                                 {
                                           writeFile();
                                                                   printf("FILE PUT DONE!\n");
                                                                 }
                                                   }
                                                 }
                         else if ((strcmp(srtp.contrl_field,FIN))==0)
                                                 {   printf("FIN RECEIVED!");
                                         synTimer(5);
                             connS.currentState = CLOSE_WAIT;
                                         cls = SRTP_Close(connS.connection_number);
                                         if (cls)
                                            connS.currentState = LAST_ACK;
                                                 }
                         else if ((strcmp(srtp.contrl_field,PUT))==0)
                             initializeBuff();
                                   }
                       else if ((connS.currentState == LAST_ACK)||(finTO))
                                   {
                         if (strcmp(srtp.contrl_field,ACK)==0)
                                                 {   finR=1;
                             printf("RECEIVED ACK ON FIN\n");
                                         printf("GOODBYE!\n");
                                         connS.currentState = CLOSED;
                                                 }
                  
                                   }
                       else if (connS.currentState == CLOSED)
                          exit(1);
                       for (int f=0;f< (MAX_SRTP_PACKET+10);f++)
                          buffer[f] = NULL; 

                 }  
                 if ((connS.currentState==LAST_ACK)&&(finTO))
                    connS.currentState=CLOSED;
         if (connS.currentState == CLOSED)
                 {
                   printf("SO FAR: \n");
                   printf("%s\n",server_buff[0].pkt.data);
                   printf("%s\n",server_buff[1].pkt.data);  
                   exit(1);
                 }
      }
 return 0;
}

Final Code: Here are all the includes and function definitions prior to beginning main



void sig_chld(int);

static int Stimer, synR, synTO,finR,finTO, maxPacket;

void synTimer(int amount)
{
   synTO=finTO=0;
  
   int processId;
  
   processId = fork();
  
   switch(processId)
   {
     case 0:
        printf("FIN timer started!\n");
        //usleep(amount);
                sleep(amount);
                printf("FIN timer expired!\n");
        _exit(0);
    
     default:
       Stimer = processId;
       //return processId;
   }
  
}

void sig_chld(int signo)
{
   int status;
   extern connection connS;
  
   waitpid(Stimer,&status,WNOHANG);
   if(WIFEXITED(status))
   { synTO=1; finTO=1;
     //if (!synR)
     if (!finR)
     {
        connS.currentState = CLOSED;
                printf("NO FIN ACK RECEIVED!\n");
     } 
     else printf("YOU WERE ACKED!\n");
   }
return;
}

int bufferPacket(srtp_header srtp)
{  extern incoming_buff server_buff[25];
   int index = (srtp.seq_num/80)-1;

   if (strcmp(srtp.contrl_field,DATL)==0)
   { 
                  maxPacket=index;
   }

   int tmp;
   
   if (!server_buff[index].received)
   {  server_buff[index].pkt= srtp;
      server_buff[index].received = 1;
      printf("Storing packet # %d\n",index);
   }
  
   int i=0, ackNum;
   while ((server_buff[i].received)&&(server_buff[i].ack_sent)&&(i<25))
      i++;
   if (strcmp(server_buff[i-1].pkt.contrl_field,DATL)==0)
   {  printf("ALL ACKS SENT!\n");
                  return -1;
   }
   else if ((server_buff[i].received) &&(!server_buff[i].ack_sent))
   {
      ackNum = (i*80)+1;
                  tmp = s_sendAckPkt(ackNum);
                  server_buff[i].ack_sent = 1;
                  if (tmp)
                                  printf("ACK SENT %d\n",ackNum);
                  return i;
   }
}

void writeFile()
{  char tempBuff[2000];
   int fileDesc;
  
   printf("INSIDE WRITE FILE\n");
  
   fileDesc = creat("testPut",448);
  
   if (fileDesc<0)
      printf("File Exists!\n");

   for (int t=0;t<25;t++)
   {
     write(fileDesc,server_buff[t].pkt.data,strlen(server_buff[t].pkt.data));

     if (strcmp(server_buff[t].pkt.contrl_field,DATL)==0)
     { 
                close(fileDesc);break;
     }
   }
return;
}

void initializeBuff()
{
  for(int i=0;i<25;i++)
  {  server_buff[i].received=0;
     server_buff[i].ack_sent=0;
  }
  return; 
}

No comments: