Sunday, 27 April 2014

Proxy Program with Cache

Cache generated only after a particular site is accessed by atleast 5 different users.



#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<netdb.h>
#include<errno.h>
#include<fstream>
using namespace std;

FILE *fp,*lp;

struct cachecount
{
 char request[100];
 int usersocks[20];
 int usernum;
 }tempcache;

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

 fp = fopen("cache.txt","w");
 char newhostname[100] = {0};
 char newpathname[100] = {0};
 int j = 0;
 int m ;
 pid_t pid;
 struct sockaddr_in address_in , server_addr , client_addr;
 struct hostent* host;
 int sockfd , newsockfd , status;

 if(argc<2)
 {
 printf("Enter Port Number\n");
 exit(0);
 }

 printf("Port Accepted \n");

 bzero((char *)&server_addr , sizeof(server_addr));
 bzero((char *)&client_addr , sizeof(client_addr));

 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(atoi(argv[1]));
 server_addr.sin_addr.s_addr = INADDR_ANY;

 printf("Intializing Socket....\n");

 sockfd = socket (AF_INET , SOCK_STREAM , IPPROTO_TCP);
 if(sockfd < 0)
 {
 printf("Intialization Failed...\n");
 exit(0);
 }

 printf("Intialization Successful....\n");

 status = bind(sockfd, (struct sockaddr*)&server_addr , sizeof(server_addr));

 if(status < 0)
 {
 printf("Error on Binding...");
 exit(0);
 }

 listen(sockfd , 60);

 printf("Listening.....\n");

 socklen_t clilength = sizeof(client_addr);

 accepting:

 newsockfd = accept(sockfd , (struct sockaddr*)&client_addr , &clilength);

 if(newsockfd < 0)
 {
 printf("Cannot Accept Connection....\n");
 exit(0);
 }

 printf("Forking......\n");

 pid = fork();

 if(pid == 0)
 {
 struct sockaddr_in hostaddr;
 int flag = 0 , forksock, newforksock , n , port = 0 , i , j ;

 char buffer[10000] , part1[400], part2[400], part3[10];

 char hostname[100] , pathname[100];

 char* temp = NULL;

 bzero((char *)buffer,10000);

 recv(newsockfd , buffer , 10000 , 0);

 sscanf(buffer,"%s %s %s",part1,part2,part3);

 // Check if the request is in right format or else terminate it.


 if(strncmp(part1,"GET",3) == 0)
 {
 if(strncmp(part2,"http://",7) == 0)
 {
 if((strncmp(part3,"HTTP/1.1",8) == 0) || (strncmp(part3,"HTTP/1.0",8) == 0))
 {

 for( i = 0 , j = 7 ; j < strlen(part2) ; i++ , j++)  // Gets our hostname
 {
 if(part2[j] == '/')
 break;
 hostname[i] = part2[j];
 }
 hostname[i] = '\0';

 host = gethostbyname(hostname);  

 for( i = 0 , j ; part2[j] != ' ' ; i++ ,j++)     // Gets our pathname
 {
 pathname[i] = part2[j] ;
 }

 port = 80 ; // default

 printf("Details Of Accepted HTTP Request\n");
 printf("Hostname : %s\n",hostname);
 printf("Pathname : %s \n",pathname);
 printf("Port : 80 \n");

 bzero((char *)&hostaddr , sizeof(hostaddr));

 hostaddr.sin_port = htons(port);
 hostaddr.sin_family = AF_INET ;

 bcopy((char*)host->h_addr,(char*)&hostaddr.sin_addr.s_addr,host->h_length);

 forksock = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);

 newforksock = connect(forksock , (struct sockaddr*)&hostaddr , sizeof(struct sockaddr));
 if(newforksock < 0)
 {
 printf("Cannot Connect...Exiting\n");
 exit(0);
 }

 sprintf(buffer ,"Connected to %s IP - %s \n",part2,inet_ntoa(hostaddr.sin_addr));

 printf("\n%s\n",buffer);

 bzero((char *)buffer , sizeof(buffer));


 if(!(strlen(pathname) > 1))
 sprintf(buffer,"GET / %s \r\nHost: %s\r\nConnection : close\r\n\r\n",part3,hostname);
 else
 sprintf(buffer,"GET %s %s\r\nHost: %s\r\nConnection : close\r\n\r\n",pathname,part3,hostname);


 n = send(forksock , buffer , strlen(buffer), 0);

 printf("\n%s\n",buffer);


 for(m = 0 ; m<strlen(pathname) ; m++)
 {
 if(pathname[m] == '/')
 {
 newpathname[m] = '-';
 }
 else
 newpathname[m] = pathname[m];
 }





 strcpy(newhostname,hostname);
 strcat(newhostname,newpathname);
 strcat(newhostname,".txt");
 int newflag = -1,y;
 ifstream opened("cache.ca",ios::binary);
  opened.clear();
  for(int x=0;!opened.eof();x++)
 {
  opened.read((char*)&tempcache,sizeof(tempcache));
  if(strcmp(newhostname,tempcache.request)==0)
  { //new flag values ---> 1 = cache this time; 2 = cache exists; 3 = No cache but has entry ... -1 = no cache, no entry
   if(tempcache.usernum == 4)
   {
    for(y=0;y<tempcache.usernum;y++)
    {
     if(newsockfd == tempcache.usersocks[y])
     {
      break;
      }
     }
    if(y == 4)
    {
     newflag = 1;
     }
   
    }
   else if (tempcache.usernum >= 5)
   {
    newflag = 2;
    }
   else
   {
    newflag = 3;
    }
    break;
   }
 }
 opened.close();
 if(newflag == -1)
 {
  fstream saved("cache.ca",ios::in|ios::out|ios::binary|ios::app);
  strcpy(tempcache.request,newhostname);
  tempcache.usernum = 1;
  tempcache.usersocks[tempcache.usernum - 1] = newsockfd;
 
  saved.write((char*)&tempcache,sizeof(tempcache));
  saved.close();
  }
 else
 {
   fstream saved1("cache.ca",ios::in|ios::out|ios::binary);
   saved1.clear();
 
    for(int z=0;!saved1.eof();z++)
    {
     saved1.read((char*)&tempcache,sizeof(tempcache));
     if(strcmp(tempcache.request,newhostname)==0)
     {
      break;
      }
     }
  int r = saved1.tellg();
   saved1.seekg(r - sizeof(tempcache));
 
   int h;
   for(h=0;h<tempcache.usernum;h++)
   {
    if(newsockfd == tempcache.usersocks[h])
    {
     break;
    }
    }
  if(h == tempcache.usernum)
  {
   tempcache.usersocks[h] = newsockfd;
   tempcache.usernum++;
   }
 
   saved1.write((char*)&tempcache,sizeof(tempcache));
   saved1.close();
  }

 fp = fopen(newhostname,"r");
 if(fp == NULL || newflag == -1 || newflag == 1 || newflag == 3)
 {
 printf("Cache Doesn't Exists...Using Internet");
 }
 else
 {
 printf("Cache Found...");
 bzero((char *)buffer,sizeof(buffer));
 while(fgets(buffer,10000,fp))
 {
 send(newsockfd , buffer , strlen(buffer) , 0);
 }
 goto cache;
 }

 if(n < 0)
 {
 printf("Error\n");
 exit(0);
 }


 // creating text file as cache with hostname's name
 if(newflag == 1)
 {
  fp = fopen(newhostname,"w");

  printf("textfile made"); }

 do
 {
 bzero((char *)buffer , 500);
 n = recv(forksock , buffer , 500, 0);
 if(n < 0)
 {
 printf("Error\n");
 exit(0);
 }
 else
 {
 if (newflag == 1)
 { fprintf(fp,buffer); }

 send(newsockfd,buffer,strlen(buffer),0);
 }
 }while(n>0);
 }
 }
 }
 else
 {
 send(newsockfd , "400 : BAD REQUEST",18,0);
 }

 close(newsockfd);
 }
 else
 goto accepting;

 cache:

 fclose(fp);
 close(sockfd);
 return 0;
}

Saturday, 26 April 2014

PC Manga Reader Beta




So I was wondering what to do with all the manga I was downloading via Dom Dom Soft when it struck me to make this little PhP based page to read them chapter by chapter.


All you need to do is the following.. 

  1. Download xampp from https://www.apachefriends.org/download.html
  2. Install it anywhere you like
  3. Download the Project Folder
  4. Copy the folder to xampp/htdocs
  5. Now start up xampp and Initiate Apache (Might start by Default)
  6. Open any browser and type "localhost/geo_reader"
  7. To read any manga, copy it to "xampp/htdocs/geo_reader/manga" (Should be in manga_name/chapter_name/--- format)
Enjoy!! ^_^

Thursday, 3 April 2014

NS2 Basics

Installing NS2.35 in Ubuntu 12.04

The following method is out-dated. Please refer this link instead
  • Download NS2.35
    (http://sourceforge.net/projects/nsnam/files/allinone/ns-allinone-2.35/nsallinone-2.35.tar.gz/download)
  • Make a new folder ns in /home and extract the files to that folder
  • Open terminal and type the following.
    • cd ns
    • cd ns-allinone-2.35
    • sudo apt-get update
    • sudo apt-get install build-essential autoconf automake libxmu-dev
    • ./install
    • sudo apt-get install xgraph
    • gedit ~/.bashrc
  • Add following lines to the file replacing "/your/path" by the folder name where you have extracted the files. Since you extracted the files to the ns folder, make "/your/path" to "home/ns" 

 # LD_LIBRARY_PATH
      OTCL_LIB=/your/path/ns-allinone-2.35/otcl-1.13      NS2_LIB=/your/path/ns-allinone-2.35/lib      X11_LIB=/usr/X11R6/lib      USR_LOCAL_LIB=/usr/local/lib    export         LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OTCL_LIB:$NS2_LIB:$X11_LIB:$USR_LOCAL_LIB    # TCL_LIBRARY      TCL_LIB=/your/path/ns-allinone-2.35/tcl8.4.18/library      USR_LIB=/usr/lib     export TCL_LIBRARY=$TCL_LIB:$USR_LIB     

# PATH     XGRAPH=/your/path/ns-allinone-2.35/bin:/your/path/ns-allinone-2.35/tcl8.4.18/unix:/your/path/      ns-        allinone- 2.35/tk8.4.18/unix    NS=/your/path/ns-allinone-2.35/ns-2.35/    NAM=/your/path/ns-allinone-2.35/nam-1.14/    PATH=$PATH:$XGRAPH:$NS:$NAM 


  • Run the following on the terminal
    • cd /home/username/ns-allinone-2.35/nam-1.15/
    • ./configure --with-tcl=/home/ns/ns-allinone-2.35/tcl-8.5.10/unix  (Don't mind the errors)
    • make
    • cd /home/ns/ns-allinone-2.35/ns-2.35
    • ./validate
    •  ./ns (Checks if ns2 is working)
  • If ns2 is working you will get a "%" prompt
  • Now copy the "nam" binary file from "/home/username/ns-allinone-2.35/nam-1.15/" to the directory "/home/username/ns-allinone-2.35/ns-2.35"
NS2 BASICS

NS2 codes are supposed written in tcl files. So make a new file with the extension tcl.
There are a few steps to be done initially to start up a network simulator.
#Creates a new Network simulator
set ns [new Simulator]
#Creates a nam file
set nf [open out.nam w]
$ns namtrace-all $nf


 #Creates a trace file
set tracefile [open trac.tr w]
$ns trace-all $tracefile

#Creates a process to be executed when the simulation is finished
proc finish {} {
        global ns nf tracefile
        $ns flush-trace
       
#Close the NAM trace file
        close $nf
        close $tracefile
        #Execute NAM on the trace file
        exec nam out.nam &
        exit 0
}
At the end of all tcl files there must be a run procedure as follows.

#This is used to schedule a function call at a particular time
#Calls procedure finish after 51seconds
$ns at 51.0 "finish"
#Procedure to run the simulator.
$ns run 
[Updating]

Tuesday, 14 January 2014

Client-Server Program to remotely Calculate Operations on 2 Natural Numbers

Client


#include <iostream>

#include <cstring>      // Needed for memset

#include <sys/socket.h> // Needed for the socket functions

#include <netdb.h>      // Needed for the socket functions

int main()

{

    int status;

    struct addrinfo host_info;       // The struct that getaddrinfo() fills up with data.

    struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's.

    memset(&host_info, 0, sizeof host_info);

    std::cout << "Setting up the structs..."  << std::endl;

    host_info.ai_family = AF_UNSPEC;     // IP version not specified. Can be both.

    host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.

    // Now fill up the linked list of host_info structs with google's address information.

    status = getaddrinfo("127.0.0.1", "5556", &host_info, &host_info_list);

    // getaddrinfo returns 0 on succes, or some other value when an error occured.

    // (translated into human readable text by the gai_gai_strerror function).

    if (status != 0)  std::cout << "getaddrinfo error" << gai_strerror(status) ;

    std::cout << "Creating a socket..."  << std::endl;

    int socketfd ; // The socket descripter

    socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,

                      host_info_list->ai_protocol);

    if (socketfd == -1)  std::cout << "socket error " ;

    std::cout << "Connect()ing..."  << std::endl;

    status = connect(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);

    if (status == -1)  std::cout << "connect error" ;

    std::cout << "send()ing message..."  << std::endl;

    char msg[20];

    std::cout<<"Enter expression: ";

    std::cin>>msg;

    int len;

    ssize_t bytes_sent;

    len = strlen(msg);

    bytes_sent = send(socketfd, msg, len, 0);

    std::cout << "Waiting to recieve data..."  << std::endl;

    ssize_t bytes_recieved;

    char incomming_data_buffer[1000];

    bytes_recieved = recv(socketfd, incomming_data_buffer,1000, 0);

    // If no data arrives, the program will just wait here until some data arrives.

    if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ;

    if (bytes_recieved == -1)std::cout << "recieve error!" << std::endl ;

    std::cout << bytes_recieved << " bytes recieved :" << std::endl ;

    incomming_data_buffer[bytes_recieved] = '\0' ;

    std::cout << incomming_data_buffer << std::endl;

    std::cout << "Receiving complete. Closing socket..." << std::endl;

    freeaddrinfo(host_info_list);

    close(socketfd);

}



Server


#include <iostream>

#include <cstring>      // Needed for memset

#include <sys/socket.h> // Needed for the socket functions

#include <netdb.h>      // Needed for the socket functions

#include <string.h>

#include <ctype.h>

int main()

{

    int status;

    struct addrinfo host_info;       // The struct that getaddrinfo() fills up with data.

    struct addrinfo *host_info_list; // Pointer to the to the linked list of host_info's.

    memset(&host_info, 0, sizeof host_info);

    std::cout << "Setting up the structs..."  << std::endl;

    host_info.ai_family = AF_UNSPEC;     // IP version not specified. Can be both.

    host_info.ai_socktype = SOCK_STREAM; // Use SOCK_STREAM for TCP or SOCK_DGRAM for UDP.

    host_info.ai_flags = AI_PASSIVE;     // IP Wildcard

    // Now fill up the linked list of host_info structs with google's address information.

    status = getaddrinfo(NULL, "5556", &host_info, &host_info_list);

    // getaddrinfo returns 0 on succes, or some other value when an error occured.

    // (translated into human readable text by the gai_gai_strerror function).

    if (status != 0)  std::cout << "getaddrinfo error" << gai_strerror(status) ;

    std::cout << "Creating a socket..."  << std::endl;

    int socketfd ; // The socket descripter

    socketfd = socket(host_info_list->ai_family, host_info_list->ai_socktype,

                      host_info_list->ai_protocol);

    if (socketfd == -1)  std::cout << "socket error " ;

    std::cout << "Binding socket..."  << std::endl;

    // we use to make the setsockopt() function to make sure the port is not in use

    // by a previous execution of our code. (see man page for more information)

    int yes = 1;

    status = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));

    status = bind(socketfd, host_info_list->ai_addr, host_info_list->ai_addrlen);

    if (status == -1)  std::cout << "bind error" << std::endl ;

    std::cout << "Listen()ing for connections..."  << std::endl;

    status =  listen(socketfd, 5);

    if (status == -1)  std::cout << "listen error" << std::endl ;

    int new_sd;

    struct sockaddr_storage their_addr;

    socklen_t addr_size = sizeof(their_addr);

    new_sd = accept(socketfd, (struct sockaddr *)&their_addr, &addr_size);

    if (new_sd == -1)

    {

        std::cout << "listen error" << std::endl ;

    }

    else

    {

        std::cout << "Connection accepted. Using new socketfd : "  <<  new_sd << std::endl;

    }

    std::cout << "Waiting to recieve data..."  << std::endl;

    ssize_t bytes_recieved;

    char incomming_data_buffer[1000];

    bytes_recieved = recv(new_sd, incomming_data_buffer,1000, 0);

    // If no data arrives, the program will just wait here until some data arrives.

    if (bytes_recieved == 0) std::cout << "host shut down." << std::endl ;

    if (bytes_recieved == -1)std::cout << "recieve error!" << std::endl ;

    std::cout << bytes_recieved << " bytes recieved :" << std::endl ;

    incomming_data_buffer[bytes_recieved] = '\0';

    

    //Checking String

    std::cout <<"Message: "<<incomming_data_buffer << std::endl;

int i,s1,s2;

s1=0;

char symbol;

char zero = '0';

for(i=0;isdigit(incomming_data_buffer[i]);i++)

{

s1 = s1*10 + (int)incomming_data_buffer[i] - (int)zero;

}

std::cout<<s1<<std::endl;

symbol = incomming_data_buffer[i];

std::cout<<symbol<<std::endl;

i+=1;

s2=0;

for(;isdigit(incomming_data_buffer[i]);i++)

{

s2 = s2*10 + (int)incomming_data_buffer[i] - (int)zero;

}

std::cout<<s2;

int result;

//Doing OPeration

switch(symbol)

{

case '+':

result = s1+s2;

break;

case '-':

result = s1-s2;

break;

case '*':

result = s1*s2;

break;

case '/':

result = s1/s2;

break;

default:

result = 0;

}

//converting to string

char number[100];

int var=0;

for(i=0;result!=0;i++)

{

var = result - ((result/10)*10);

result/=10;

number[i]=(char)var + (char)zero;

}

number[i]='\0';

//reversing string

i=i-1;

int x;

char message[100];

for(x=0;i>=0;i--,x++)

{

message[x] = number[i];

}

message[x] = '\0';

    std::cout << "send()ing back a message..."  << std::endl;

    

    int len;

    ssize_t bytes_sent;

    len = strlen(message);

    bytes_sent = send(new_sd, message, len, 0);

    std::cout << "Stopping server..." << std::endl;

    freeaddrinfo(host_info_list);

    close(new_sd);

    close(socketfd);

return 0 ;

}