int main(int argc, char **argv) { int sockfd[10], sockcount = 0, countline = 0, n = 0, s, nready, maxfdp1, i; fd_set rset, allset; socklen_t len, slen; const int on = 1; pid_t pid; struct ifi_info *ifi, *ifihead; struct sockaddr_in *sa, cliaddr, wildaddr, ss,childservaddr; char dataline[MAXLINE], mesg[MAXLINE], IPClient[MAXLINE],IPServer[MAXLINE]; config configdata[2]; char *mode = "r"; socket_info sockinfo[10]; FILE *ifp; int is_local = 0; ifp = fopen( "server.in", mode ); if ( ifp == NULL ) { fprintf( stderr, "Can't open input file server.in!\n" ); exit(1); } printf("***********************************************************************************\n"); printf("SERVER \n"); printf("***********************************************************************************\n"); while ( fgets( dataline,MAXLINE,ifp ) != NULL ) { n = strlen( dataline ); strcpy( configdata[countline].data, dataline ); s = strlen( configdata[ countline ].data ); if ( s > 0 && configdata[ countline ].data[ s-1 ] == '\n' ) /* if there's a newline */ { configdata[countline].data[s-1] = '\0'; /* truncate the string */ } dataline[n] = 0; countline++; } fclose( ifp ); printf("Creating the send window array dynamically for input window size..\n\n"); sender_window_size = (int) atoi( configdata[1].data ); swnd = (struct msghdr *) malloc( sender_window_size*sizeof( struct msghdr ) ); for ( ifihead = ifi = get_ifi_info_plus( AF_INET, 1 ); ifi != NULL; ifi = ifi->ifi_next) { sockfd[sockcount]=-1; printf("Total sockets bound : %d\n",sockcount); int x = 0; /*4bind unicast address */ if( ( sockfd[ sockcount ] = socket( AF_INET, SOCK_DGRAM, 0 ) ) == NULL ) { printf( "socket error\n" ); exit(1); } setsockopt( sockfd[sockcount], SOL_SOCKET, SO_REUSEADDR, &on, sizeof( on ) ); sa = ( struct sockaddr_in * )ifi->ifi_addr; sa->sin_family = AF_INET; sa->sin_port = htonl( ((int) atoi( configdata[0].data) )); // sa->sin_port = htonl( 12345 ); bind( sockfd[sockcount], (SA *) sa, sizeof( struct sockaddr_in ) ); slen = sizeof( ss ); if( getsockname( sockfd[sockcount], (SA *)&ss, &slen ) < 0 ) { printf( "sockname error\n" ); exit(1); } printf("\nBOUND SOCKET ADDRESSES : %s\n", inet_ntop( AF_INET, &(ss.sin_addr), IPClient, MAXLINE )); printf( "SERVER PORT: %d\n", ss.sin_port ); sockinfo[ sockcount ].sockfd = sockfd[ sockcount ]; sockinfo[ sockcount ].ip_addr = (SA *)sa; sockinfo[ sockcount ].ntmaddr = (struct sockaddr_in *)ifi->ifi_ntmaddr; //sockinfo[sockcount].subnetaddr=ifi->sockfd[sockcount]; printf( "\nSocket File Descriptor : %d\n", sockinfo[ sockcount ].sockfd ); printf( "IP addr: %s\n", sock_ntop_host( (SA *)sockinfo[sockcount].ip_addr, sizeof( *sockinfo[sockcount].ip_addr ) ) ); printf( "Network Mask : %s\n", sock_ntop_host( (SA *)sockinfo[sockcount].ntmaddr, sizeof(*sockinfo[sockcount].ntmaddr ) ) ); sockcount++; // if ( (pid = fork()) == 0) { /* child */ // mydg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr), (SA *) sa); // exit(0); /* never executed */ // } /* end udpserv1 */ } maxfdp1 = -1; FD_ZERO( &allset ); for( i = 0; i<sockcount; i++ ) { FD_SET( sockinfo[ i ].sockfd, &allset ); if( sockinfo[ i ].sockfd > maxfdp1 ) { maxfdp1 = sockinfo[ i ].sockfd; } } for ( ; ; ) { rset = allset; if ( ( nready = select( maxfdp1 + 1, &rset, NULL, NULL, NULL ) ) < 0 ) { if ( errno == EINTR ) continue; /* back to for() */ else err_sys("select error"); } for( i = 0; i<sockcount; i++ ) { if( FD_ISSET( sockinfo[ i ].sockfd, &rset ) ) { len = sizeof( cliaddr ); char hsMsg[PACKET_SIZE]; char recvBufStr[PACKET_SIZE]; n = recvfrom( sockinfo[ i ].sockfd, hsMsg, PACKET_SIZE, 0, (SA *) &cliaddr, &len ); printf("\nMESSAGE RECIEVED FROM CLIENT : %s\n", hsMsg ); sscanf(hsMsg,"%s %s",mesg,recvBufStr); recv_window_size=atoi(recvBufStr); inet_ntop( AF_INET, &cliaddr.sin_addr, IPClient, MAXLINE ); printf("CLIENT ADDRESS : %s\n\n",IPClient ); /* Returns which interface onto which the client has connected. */ if( getsockname( sockinfo[ i ].sockfd, (SA *)&ss, &slen ) < 0 ) { printf( "sockname error\n" ); exit(1); } printf("\nCONNECTION RECEIVED ON :\n "); printf("BOUND SOCKET ADDRESS : %s\n", inet_ntop( AF_INET, &(ss.sin_addr), IPServer, MAXLINE )); printf( "SERVER PORT: %d\n", ss.sin_port ); // printf( "sockfd----- %d\n", sockinfo[ i ].sockfd ); printf("\nChecking if Server is LOCAL to client..\n"); if( strcmp( IPServer, "127.0.0.1\n" ) == 0 ) { printf("STATUS : SAME HOST\nCLIENT ADDRESS : %s\nSERVER ADDRESS : %s\n", IPClient, IPServer ); is_local = 1; } else { struct in_addr ip, netmask, subnet, clientip, default_ip; struct in_addr longest_prefix_ip, longest_prefix_netmask; char network1[MAXLINE], network2[MAXLINE], ip1[MAXLINE], nm1[MAXLINE]; struct sockaddr_in *sd = (struct sockaddr_in *)(sockinfo[ i ].ip_addr); struct sockaddr_in *se = (struct sockaddr_in *)(sockinfo[ i ].ntmaddr); ip = sd->sin_addr; netmask = se->sin_addr; subnet.s_addr = ip.s_addr & netmask.s_addr; inet_ntop( AF_INET, &subnet, network1, MAXLINE ); inet_ntop( AF_INET, &ip, ip1, MAXLINE ); inet_ntop( AF_INET, &netmask, nm1, MAXLINE ); inet_pton( AF_INET, IPClient, &clientip ); subnet.s_addr = clientip.s_addr & netmask.s_addr; inet_ntop( AF_INET, &subnet, network2, MAXLINE ); if( strcmp( network1, network2 ) == 0 ) { /* LOCAL */ printf("STATUS : LOCAL\nCLIENT ADDRESS (IPClient) : %s\nSERVER ADDRESS (IPServer) : %s\n", IPClient, IPServer ); is_local = 1; } else { printf("STATUS : NOT LOCAL\nCLIENT ADDRESS : %s\nSERVER ADDRESS : %s\n", IPClient, IPServer ); is_local = 0; } } /* Filling up the child server address structure. */ childservaddr.sin_family = AF_INET; childservaddr.sin_port = htonl( 0 ); inet_pton( AF_INET, IPServer, &childservaddr.sin_addr ); slen = sizeof( ss ); inet_pton( AF_INET, IPServer, &childservaddr.sin_addr ); if ( ( pid = fork() ) == 0 ) { /* child */ if( is_local == 1 ) { setsockopt( sockinfo[ i ].sockfd, SOL_SOCKET, SO_DONTROUTE, &on, sizeof( on ) ) ; } mydg_echo( sockinfo[ i ].sockfd, (SA *) &childservaddr, sizeof(childservaddr), (SA *) &cliaddr, sizeof(cliaddr), mesg ); exit(0); /* never executed */ } } } } exit(0); }
int main(int argc, char **argv) { //int sockfd; int flag_local =0; int flag_same =0; struct ifi_info *ifi; struct ifi_info *ifiClient; struct sockaddr_in *sin, *mask, *locAddr, *tempAddr; struct sockaddr_in servaddr, cliaddr; char serverStr[INET_ADDRSTRLEN], clientStr[INET_ADDRSTRLEN]; struct sockaddr *sa; bzero(&servaddr, sizeof(servaddr)); bzero(&cliaddr, sizeof(cliaddr)); memset(serverStr, 0, INET_ADDRSTRLEN); memset(clientStr, 0, INET_ADDRSTRLEN); client_args c_arguments; memset(&c_arguments, 0, sizeof(c_arguments)); if(RET_FAILURE == read_client_input_file(&c_arguments)) { exit(RET_FAILURE); } #ifdef DEBUG printf("IP address: %s\n", c_arguments.ipAddress); printf("Port number: %d\n", c_arguments.port_number); printf("File to send: %s\n", c_arguments.file_name); printf("Window size: %d\n", c_arguments.window_size); printf("Seed: %d\n", c_arguments.seed); printf("Probability: %f\n", c_arguments.probability); printf("Mean time: %d\n", c_arguments.mean_time); #endif unsigned long serverAddress=0; unsigned long temp=0, tempMask=0; unsigned long longestNetMask=0, longestNetMaskDiff =0; //Diff for server if on different network char* serverIPAddress = c_arguments.ipAddress; char* loopBack = "127.0.0.1"; unsigned long loopBackAddress =0; inet_pton(AF_INET, loopBack, &loopBackAddress); inet_pton(AF_INET, serverIPAddress, &servaddr.sin_addr); /* ** Step 1 ** To check whether the server is local or not */ for(ifi = get_ifi_info_plus(AF_INET, 1); ifi != NULL; ifi=ifi->ifi_next) { mask = ((struct sockaddr_in *)ifi->ifi_ntmaddr); locAddr = ((struct sockaddr_in *)ifi->ifi_addr); if((servaddr.sin_addr.s_addr & mask->sin_addr.s_addr) == (locAddr->sin_addr.s_addr & mask->sin_addr.s_addr)) { //To check Whether the server is on same network, if yes choose the highest precision netmask address flag_local = 1; temp = mask->sin_addr.s_addr; printf("MAsk of the interface : %ld\n", temp); if(temp > longestNetMask) { longestNetMask = temp; ifiClient = ifi; } //printf("Server is on the host itself \n"); if(servaddr.sin_addr.s_addr == locAddr->sin_addr.s_addr) { flag_same = 1; } } else { tempMask = mask->sin_addr.s_addr; if(tempMask > longestNetMaskDiff) { longestNetMaskDiff = temp; ifiClient = ifi; } } printf("Information for an interface\n"); printf("Name : %s\n", ifi->ifi_name); printf("Address : %s\n", my_sock_ntop(ifi->ifi_addr, sizeof(struct sockaddr))); printf("NetWork Mask : %s\n",my_sock_ntop(ifi->ifi_ntmaddr, sizeof(struct sockaddr))); printf("\n"); } if(flag_same == 1) { servaddr.sin_addr.s_addr = loopBackAddress; locAddr->sin_addr.s_addr = loopBackAddress; cliaddr.sin_addr.s_addr = loopBackAddress; } else if(flag_local == 1) { locAddr = ((struct sockaddr_in *)ifiClient->ifi_addr); cliaddr.sin_addr = locAddr->sin_addr; } else { locAddr = ((struct sockaddr_in *)ifiClient->ifi_addr); cliaddr.sin_addr = locAddr->sin_addr; } //printf("IS server on same network = %d\n Is server Local =%d \n", flag_same, flag_local); if(inet_ntop(AF_INET,&servaddr.sin_addr, serverStr, sizeof(serverStr)) <= 0) { perror("INET_PTON error:"); } /*if(inet_ntop(AF_INET,&locAddr->sin_addr, clientStr, sizeof(clientStr)) <= 0) { perror("INET_PTON error:"); }*/ if(inet_ntop(AF_INET,&cliaddr.sin_addr, clientStr, sizeof(clientStr)) <= 0) { perror("INET_PTON error:"); } //printf("Server address: %s\n",serverStr); //printf("Client Address: %s\n", clientStr); /* ** Step 2 ** Bind the UDP Socket to that client and server Address */ int sockfd; sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0) { perror("Error while creating UDP Socket:"); exit(1); } if(flag_same == 1) { int optval =1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR | SO_DONTROUTE, &optval, sizeof optval); } cliaddr.sin_family = AF_INET; cliaddr.sin_port = htons(0); if(bind(sockfd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0) { perror("Bind error:"); exit(1); } struct sockaddr_in cliSock; socklen_t len; bzero(&cliSock, sizeof(cliSock)); len = sizeof(cliSock); if(getsockname(sockfd, (struct sockaddr *) &cliSock, &len) < 0) { perror("Get Socket Name error:"); exit(1); } printf("Client Binded to %s:%u\n",inet_ntoa(cliSock.sin_addr), ntohs(cliSock.sin_port)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(c_arguments.port_number); //printf("Sever port : %d %d\n", servaddr.sin_port,MY_SERV_PORT); if(connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr))< 0) { perror("Server Connection Failed:"); exit(1); } struct sockaddr_in servSock; //socklen_t len; bzero(&servSock, sizeof(servSock)); len = sizeof(servSock); if(getpeername(sockfd, (struct sockaddr*)&servSock, &len) < 0) { perror("Getpeername failed :"); exit(1); } printf("Server address %s:%u\n",inet_ntoa(servSock.sin_addr), ntohs(servSock.sin_port)); /* ** Step 3 ** Start acknowledgement with the server */ fileClient(sockfd, &servaddr, sizeof(servaddr), &c_arguments); }