stub-monitor.c 6.85 KB
Newer Older
Robert Ricci's avatar
Robert Ricci committed
1 2
/*
 * Copyright (c) 2006 University of Utah and the Flux Group.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * 
 * {{{EMULAB-LICENSE
 * 
 * This file is part of the Emulab network testbed software.
 * 
 * This file is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This file is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
 * License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this file.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * }}}
Robert Ricci's avatar
Robert Ricci committed
22 23
 */

Junxing Zhang's avatar
Junxing Zhang committed
24 25 26 27 28 29
/*
** monitor.c -- a tcp client that works as the monitor 
*/

#include "stub.h"

30 31
char public_hostname0[128]; //= "planetlab1.cs.dartmouth.edu"; // "planet0.measure.tbres.emulab.net"; 
char public_hostname1[128]; //= "pl1.cs.utk.edu"; // "planet1.measure.tbres.emulab.net";
Junxing Zhang's avatar
Junxing Zhang committed
32 33
char public_addr0[16];
char public_addr1[16];
34
char private_addr0[]="10.1.0.1"; //for testing on emulab only
Junxing Zhang's avatar
Junxing Zhang committed
35
char private_addr1[]="10.1.0.2";
36
short  flag_debug;
Junxing Zhang's avatar
Junxing Zhang committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
fd_set read_fds,write_fds;

void print_header(char *buf){
  int i, j, len=12;

  printf("Buffer header len: %d \n", len);
  for (i=0; i<len; i++){
    j = buf[i] & 0x000000ff;
    printf("%d: %u \n", i, j); 
  }
}

void send_stub(int sockfd, char *addr, char *buf) {
  struct in_addr address;
  unsigned long   tmpulong;

53
  tmpulong = htonl(127L); //no use for now
Junxing Zhang's avatar
Junxing Zhang committed
54
  memcpy(buf, &tmpulong, SIZEOF_LONG);
55
  tmpulong = htonl(1L); //1 destinate
Junxing Zhang's avatar
Junxing Zhang committed
56
  memcpy(buf+SIZEOF_LONG, &tmpulong, SIZEOF_LONG);
57

Junxing Zhang's avatar
Junxing Zhang committed
58 59
  inet_aton(addr, &address);
  tmpulong = address.s_addr;
60
  if (flag_debug) {
61 62
    //printf("tmpulong: %lu \n", tmpulong);
    printf("send the stub a probing address: %s \n", inet_ntoa(address));
Junxing Zhang's avatar
Junxing Zhang committed
63 64
  }
  memcpy(buf+SIZEOF_LONG+SIZEOF_LONG, &tmpulong, SIZEOF_LONG);
65 66 67 68 69
  tmpulong = htonl(5L); //interdeparture 5 ms
  memcpy(buf+3*SIZEOF_LONG, &tmpulong, SIZEOF_LONG);
  tmpulong = htonl(80L); //packet size 80
  memcpy(buf+4*SIZEOF_LONG, &tmpulong, SIZEOF_LONG);

Junxing Zhang's avatar
Junxing Zhang committed
70
  //should use send_all()!
71
  if (send(sockfd, buf, 5*SIZEOF_LONG, 0) == -1){
Junxing Zhang's avatar
Junxing Zhang committed
72 73 74 75 76 77 78 79 80 81 82 83 84
    perror("ERROR: send_stub() - send()");
    exit(1);
  }    
}

void receive_stub(int sockfd, char *buf) {
  int numbytes;

  if ((numbytes=recv(sockfd, buf, 3*SIZEOF_LONG, 0)) == -1) {
    perror("recv");
    exit(1);
  }
    
85
  if (flag_debug) {
Junxing Zhang's avatar
Junxing Zhang committed
86 87 88 89 90 91 92 93
    print_header(buf);
    printf("numbytes: %d \n", numbytes);
  }    

}

int have_time(struct timeval *start_tvp, struct timeval *left_tvp){
  struct timeval current_tv;
94
  long long   left_usec, past_usec; //64-bit integer
Junxing Zhang's avatar
Junxing Zhang committed
95 96

  gettimeofday(&current_tv, NULL);
97
  past_usec = ((long long)(current_tv.tv_sec-start_tvp->tv_sec))*1000000+
Junxing Zhang's avatar
Junxing Zhang committed
98
    (current_tv.tv_usec-start_tvp->tv_usec);
Junxing Zhang's avatar
Junxing Zhang committed
99
  left_usec = QUANTA*1000-past_usec; //QUANTA is in msec
Junxing Zhang's avatar
Junxing Zhang committed
100 101 102 103 104 105 106 107 108 109
  if (left_usec > 0) {
    left_tvp->tv_sec = left_usec/1000000;
    left_tvp->tv_usec= left_usec%1000000;
    return 1;
  }
  return 0;
}

int main(int argc, char *argv[])
{
Junxing Zhang's avatar
Junxing Zhang committed
110
  int sockfd0, sockfd1;  
Junxing Zhang's avatar
Junxing Zhang committed
111 112 113 114
  fd_set read_fds_copy, write_fds_copy;
  struct timeval start_tv, left_tv;
  char buf[MAX_PAYLOAD_SIZE];
  struct sockaddr_in their_addr; // connector's address information 
Junxing Zhang's avatar
Junxing Zhang committed
115 116 117 118 119
  int maxfd, yes=1, flag_send_stub0=0,flag_send_stub1=0 ;
  struct hostent *hp;
  struct in_addr addr;
  char *ip;

120 121 122 123 124 125
  //set up debug flag
  if (getenv("Debug")!=NULL) 
    flag_debug=1;
  else 
    flag_debug=0;

126 127 128 129 130 131 132 133 134 135
  if (argc != 3) {
    fprintf(stderr,"Usage: stub-monitor <hostname1> <hostname2>\n");
    exit(1);
  }
  strcpy(public_hostname0, argv[1]);
  strcpy(public_hostname1, argv[2]);
  if (flag_debug) {
    printf("hostname1: %s, hostname2: %s\n", public_hostname0, public_hostname1);
  }

Junxing Zhang's avatar
Junxing Zhang committed
136 137 138 139
  hp = gethostbyname(public_hostname0);
  bcopy(hp->h_addr, &addr, hp->h_length);
  ip = inet_ntoa(addr);
  strcpy(public_addr0, ip);
140
  if (flag_debug) {
141
    printf("public_addr0: %s \n", public_addr0);
142
  }
Junxing Zhang's avatar
Junxing Zhang committed
143 144 145 146
  hp = gethostbyname(public_hostname1);
  bcopy(hp->h_addr, &addr, hp->h_length);
  ip = inet_ntoa(addr);
  strcpy(public_addr1, ip);
147
  if (flag_debug) {
148
    printf("public_addr1: %s \n", public_addr1);
149 150
  }

Junxing Zhang's avatar
Junxing Zhang committed
151 152

  if ((sockfd0 = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
153 154 155
    perror("socket");
    exit(1);
  }
Junxing Zhang's avatar
Junxing Zhang committed
156
  if (setsockopt(sockfd0, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
157 158 159 160 161
    perror("setsockopt");
    exit(1);
  }
  their_addr.sin_family = AF_INET;    // host byte order 
  their_addr.sin_port = htons(MONITOR_PORT);  // short, network byte order 
Junxing Zhang's avatar
Junxing Zhang committed
162
  inet_aton(public_addr0, &(their_addr.sin_addr)); //contact the stub through the control network!
Junxing Zhang's avatar
Junxing Zhang committed
163
  memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct 
Junxing Zhang's avatar
Junxing Zhang committed
164
  if (connect(sockfd0, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
165 166 167 168
    perror("connect1");
    exit(1);
  }
  
Junxing Zhang's avatar
Junxing Zhang committed
169
  if ((sockfd1 = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
170 171 172
    perror("socket");
	    exit(1);
  }
Junxing Zhang's avatar
Junxing Zhang committed
173
  if (setsockopt(sockfd1, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
174 175 176
    perror("setsockopt");
    exit(1);
  }
Junxing Zhang's avatar
Junxing Zhang committed
177 178
  inet_aton(public_addr1, &(their_addr.sin_addr));
  if (connect(sockfd1, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
Junxing Zhang's avatar
Junxing Zhang committed
179 180
    perror("connect2");
    exit(1);
Junxing Zhang's avatar
Junxing Zhang committed
181 182
  } 

Junxing Zhang's avatar
Junxing Zhang committed
183 184 185 186 187
  //initialization
  FD_ZERO(&read_fds);
  FD_ZERO(&read_fds_copy);
  FD_ZERO(&write_fds);
  FD_ZERO(&write_fds_copy);
Junxing Zhang's avatar
Junxing Zhang committed
188
  FD_SET(sockfd0, &read_fds);
Junxing Zhang's avatar
Junxing Zhang committed
189
  FD_SET(sockfd1, &read_fds);
Junxing Zhang's avatar
Junxing Zhang committed
190
  FD_SET(sockfd0, &write_fds);
Junxing Zhang's avatar
Junxing Zhang committed
191
  FD_SET(sockfd1, &write_fds);
Junxing Zhang's avatar
Junxing Zhang committed
192
  maxfd = sockfd1; //socket order
Junxing Zhang's avatar
Junxing Zhang committed
193 194 195 196

  //main loop - the monitor runs forever
  while (1) {
    gettimeofday(&start_tv, NULL); //reset start time for each quanta
Junxing Zhang's avatar
Junxing Zhang committed
197
    flag_send_stub0=0;
Junxing Zhang's avatar
Junxing Zhang committed
198 199 200 201 202 203 204 205 206 207 208 209
    flag_send_stub1=0;

    //while in a quanta
    while(have_time(&start_tv, &left_tv)) {  
      read_fds_copy  = read_fds;
      write_fds_copy = write_fds;

      if (select(maxfd+1, &read_fds_copy, &write_fds_copy, NULL, &left_tv) == -1) { 
	perror("select"); 
	exit(1); 
      }
      //check write
Junxing Zhang's avatar
Junxing Zhang committed
210
      if (flag_send_stub0==0 && FD_ISSET(sockfd0, &write_fds_copy)) {
211 212 213
	if (flag_debug) {
	  printf("send to: %s \n", public_addr0);
	}
214
	send_stub(sockfd0, private_addr1, buf); //feed the stub with the private or public address
Junxing Zhang's avatar
Junxing Zhang committed
215 216 217
	flag_send_stub0=1;
      } 

Junxing Zhang's avatar
Junxing Zhang committed
218
      if (flag_send_stub1==0 && FD_ISSET(sockfd1, &write_fds_copy)) {
219 220 221
	if (flag_debug) {
	  printf("send to: %s \n", public_addr1);
	}
222
	send_stub(sockfd1, private_addr0, buf); //feed the stub with the private or public address
Junxing Zhang's avatar
Junxing Zhang committed
223 224 225
	flag_send_stub1=1;
      } 

Junxing Zhang's avatar
Junxing Zhang committed
226 227
      //check read
      if (FD_ISSET(sockfd0, &read_fds_copy)) {
228 229 230
	if (flag_debug) {
	  printf("received from %s \n", public_addr0);
	}
Junxing Zhang's avatar
Junxing Zhang committed
231
	receive_stub(sockfd0,buf);
Junxing Zhang's avatar
Junxing Zhang committed
232 233 234
      } 

      if (FD_ISSET(sockfd1, &read_fds_copy)) {
235 236 237
	if (flag_debug) {
	  printf("received from %s \n", public_addr1);
	}
Junxing Zhang's avatar
Junxing Zhang committed
238 239 240 241 242 243
	receive_stub(sockfd1,buf);
      } 

    } //while in a quanta
  } //while forever

Junxing Zhang's avatar
Junxing Zhang committed
244
  close(sockfd0);
Junxing Zhang's avatar
Junxing Zhang committed
245 246 247
  close(sockfd1);
  return 0;
}