Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
some more work on the bandwidth test module (ie, root of ALNeM) modernization. Still...
[simgrid.git] / src / amok / Bandwidth / bandwidth.c
1 /* $Id$ */
2
3 /* amok_bandwidth - Bandwidth tests facilities    */
4
5 /* Authors: Martin Quinson                                                  */
6 /* Copyright (C) 2003, 2004 the OURAGAN project.                            */
7
8 /* This program is free software; you can redistribute it and/or modify it
9    under the terms of the license (GNU LGPL) which comes with this package. */
10
11 #include "amok/Bandwidth/bandwidth_private.h"
12 #include "gras/messages.h"
13
14 GRAS_LOG_NEW_DEFAULT_SUBCATEGORY(bw,amok,"Bandwidth testing");
15
16 static short _amok_bw_initialized = 0;
17
18 /**** code ****/
19 void amok_bw_init(void) {
20   gras_error_t errcode;
21   gras_datadesc_type_t bw_request_desc, bw_res_desc, sat_request_desc;
22
23   if (_amok_bw_initialized)
24      return;
25    
26   amok_base_init();
27    
28   /* Build the datatype descriptions */ 
29   bw_request_desc = gras_datadesc_struct("s_bw_request_t");
30   gras_datadesc_struct_append(bw_request_desc,"host",gras_datadesc_by_name("gras_host_t"));
31   gras_datadesc_struct_append(bw_request_desc,"buf_size",gras_datadesc_by_name("unsigned int"));
32   gras_datadesc_struct_append(bw_request_desc,"exp_size",gras_datadesc_by_name("unsigned int"));
33   gras_datadesc_struct_append(bw_request_desc,"msg_size",gras_datadesc_by_name("unsigned int"));
34   gras_datadesc_struct_close(bw_request_desc);
35   bw_request_desc = gras_datadesc_ref("bw_request_t",bw_request_desc);
36
37   bw_res_desc = gras_datadesc_struct("s_bw_res_t");
38   gras_datadesc_struct_append(bw_res_desc,"err",gras_datadesc_by_name("s_amok_remoterr_t"));
39   gras_datadesc_struct_append(bw_res_desc,"timestamp",gras_datadesc_by_name("unsigned int"));
40   gras_datadesc_struct_append(bw_res_desc,"seconds",gras_datadesc_by_name("double"));
41   gras_datadesc_struct_append(bw_res_desc,"bw",gras_datadesc_by_name("double"));
42   gras_datadesc_struct_close(bw_res_desc);
43   bw_res_desc = gras_datadesc_ref("bw_res_t",bw_res_desc);
44
45   sat_request_desc = gras_datadesc_struct("s_sat_request_desc_t");
46   gras_datadesc_struct_append(sat_request_desc,"host",gras_datadesc_by_name("gras_host_t"));
47   gras_datadesc_struct_append(sat_request_desc,"msg_size",gras_datadesc_by_name("unsigned int"));
48   gras_datadesc_struct_append(sat_request_desc,"timeout",gras_datadesc_by_name("unsigned int"));
49   gras_datadesc_struct_close(sat_request_desc);
50   sat_request_desc = gras_datadesc_ref("sat_request_t",sat_request_desc);
51    
52   /* Register the bandwidth messages */
53   gras_msgtype_declare("BW request",       bw_request_desc);
54   gras_msgtype_declare("BW result",        bw_res_desc);
55   gras_msgtype_declare("BW handshake",     bw_request_desc);
56   gras_msgtype_declare("BW handshake ACK", bw_request_desc);
57
58   /* Register the saturation messages */
59   gras_msgtype_declare("SAT start",   sat_request_desc);
60   gras_msgtype_declare("SAT started", gras_datadesc_by_name("amok_remoterr_t"));
61   gras_msgtype_declare("SAT begin",   sat_request_desc);
62   gras_msgtype_declare("SAT begun",   gras_datadesc_by_name("amok_remoterr_t"));
63   gras_msgtype_declare("SAT end",     NULL);
64   gras_msgtype_declare("SAT ended",   gras_datadesc_by_name("amok_remoterr_t"));
65   gras_msgtype_declare("SAT stop",    NULL);
66   gras_msgtype_declare("SAT stopped", gras_datadesc_by_name("amok_remoterr_t"));
67
68   /* Register the callbacks */
69   gras_cb_register(gras_msgtype_by_name("BW request"),
70                    &amok_bw_cb_bw_request);
71   gras_cb_register(gras_msgtype_by_name("BW handshake"),
72                    &amok_bw_cb_bw_handshake);
73
74   gras_cb_register(gras_msgtype_by_name("SAT start"),
75                    &amok_bw_cb_sat_start);
76   gras_cb_register(gras_msgtype_by_name("SAT begin"),
77                    &amok_bw_cb_sat_begin);
78   
79   _amok_bw_initialized =1;
80 }
81
82 void amok_bw_exit(void) {
83   if (! _amok_bw_initialized)
84     return;
85    
86   gras_cb_unregister(gras_msgtype_by_name("BW request"),
87                      &amok_bw_cb_bw_request);
88   gras_cb_unregister(gras_msgtype_by_name("BW handshake"),
89                      &amok_bw_cb_bw_handshake);
90
91   gras_cb_unregister(gras_msgtype_by_name("SAT start"),
92                      &amok_bw_cb_sat_start);
93   gras_cb_unregister(gras_msgtype_by_name("SAT begin"),
94                      &amok_bw_cb_sat_begin);
95
96   _amok_bw_initialized = 0;
97 }
98
99    
100
101 /* ***************************************************************************
102  * Bandwidth tests
103  * ***************************************************************************/
104
105 /**
106  * amok_bw_test:
107  * 
108  * Conduct a test between the local host and @peer, and 
109  * report the result in last args
110  */
111 gras_error_t amok_bw_test(gras_socket_t peer,
112                           unsigned int buf_size,unsigned int exp_size,unsigned int msg_size,
113                           /*OUT*/ double *sec, double *bw) {
114   gras_socket_t rawIn,rawOut; /* raw sockets for the experiments */
115   gras_socket_t sock_dummy; /* ignored arg to msg_wait */
116   int port;
117   gras_error_t errcode;
118   bw_request_t request,request_ack;
119   
120   for (port = 5000, errcode = system_error;
121        errcode == system_error;
122        errcode = gras_socket_server_ext(++port,buf_size,1,&rawIn));
123   if (errcode != no_error) {
124     ERROR1("Error %s encountered while opening a raw socket",
125            gras_error_name(errcode));
126     return errcode;
127   }
128         
129   request=gras_new0(s_bw_request_t,1);
130   request->buf_size=buf_size;
131   request->exp_size=exp_size;
132   request->msg_size=msg_size;
133   request->host.name = NULL;
134   request->host.port = gras_socket_my_port(rawIn);
135   INFO1("Send an handshake to get the dude connect to port %d on me", request->host.port);
136
137   if ((errcode=gras_msg_send(peer,gras_msgtype_by_name("BW handshake"),&request))) {
138     ERROR1("Error %s encountered while sending the BW request.", gras_error_name(errcode));
139     return errcode;
140   }
141   if ((errcode=gras_msg_wait(60,gras_msgtype_by_name("BW handshake ACK"),&sock_dummy,&request_ack))) {
142     ERROR1("Error %s encountered while waiting for the answer to BW request.\n",
143             gras_error_name(errcode));
144     return errcode;
145   }
146    
147   /* FIXME: What if there is a remote error? */
148    
149   if((errcode=gras_socket_client_ext(gras_socket_peer_name(peer),request_ack->host.port, buf_size,1,&rawOut))) {
150     ERROR3("Error %s encountered while opening the raw socket to %s:%d for BW test\n",
151             gras_error_name(errcode),gras_socket_peer_name(peer),request_ack->host.port);
152     return errcode;
153   }
154   gras_free(request_ack);
155   INFO0("Got ACK");
156
157   *sec=gras_os_time();
158   if ((errcode=gras_socket_raw_send(rawOut,120,exp_size,msg_size)) ||
159       (errcode=gras_socket_raw_recv(rawIn,120,1,1))) {
160     ERROR1("Error %s encountered while sending the BW experiment.",
161             gras_error_name(errcode));
162     gras_socket_close(rawOut);
163     gras_socket_close(rawIn);
164     return errcode;
165   }
166   *sec = gras_os_time() - *sec;
167   *bw = ((double)exp_size /* 8.0*/) / *sec / (1024.0 *1024.0);
168 INFO0("DOOONE");
169    
170   gras_socket_close(rawIn);
171   gras_socket_close(rawOut);
172   return no_error;
173 }
174
175
176 /* Callback to the "BW handshake" message: 
177    opens a server raw socket,
178    indicate its port in an "BW handshaked" message,
179    receive the corresponding data on the raw socket, 
180    close the raw socket
181 */
182 int amok_bw_cb_bw_handshake(gras_socket_t  expeditor,
183                             void          *payload) {
184   gras_socket_t rawIn,rawOut;
185   bw_request_t request=*(bw_request_t*)payload;
186   bw_request_t answer;
187   gras_error_t errcode;
188   int port;
189   
190   INFO2("Got an handshake to connect to %s:%d",
191         request->host.name,request->host.port);
192      
193   answer = gras_new0(s_bw_request_t,1);
194   
195   for (port = 5000, errcode = system_error;
196        errcode == system_error;
197        errcode = gras_socket_server_ext(++port,request->buf_size,1,&rawIn));
198   if (errcode != no_error) {
199     ERROR1("Error %s encountered while opening a raw socket", gras_error_name(errcode));
200     /* FIXME: tell error to remote */
201     return 1;
202   }
203
204   if ((errcode=gras_socket_client_ext(gras_socket_peer_name(expeditor),request->host.port,
205                                       request->buf_size,1,&rawOut))) { 
206     ERROR3("Error '%s' encountered while opening a raw socket to %s:%d", 
207            gras_error_name(errcode),gras_socket_peer_name(expeditor),request->host.port);
208     /* FIXME: tell error to remote */
209     return 1;
210   }
211    
212   answer->buf_size=request->buf_size;
213   answer->exp_size=request->exp_size;
214   answer->msg_size=request->msg_size;
215   answer->host.port=gras_socket_my_port(rawIn);
216
217   if ((errcode=gras_msg_send(expeditor,gras_msgtype_by_name("BW handshake ACK"),&answer))) {
218     ERROR1("Error %s encountered while sending the answer.",
219             gras_error_name(errcode));
220     gras_socket_close(rawIn);
221     gras_socket_close(rawOut);
222     /* FIXME: tell error to remote */
223     return 1;
224   }
225   INFO4("BW handshake answered. buf_size=%d exp_size=%d msg_size=%d port=%d",
226         answer->buf_size,answer->exp_size,answer->msg_size,answer->host.port);
227     
228   if ((errcode=gras_socket_raw_recv(rawIn, 120,request->exp_size,request->msg_size)) ||
229       (errcode=gras_socket_raw_send(rawOut,120,1,1))) {
230     ERROR1("Error %s encountered while receiving the experiment.",
231             gras_error_name(errcode));
232     gras_socket_close(rawIn);
233     gras_socket_close(rawOut);
234     /* FIXME: tell error to remote ? */
235     return 1;
236   }
237   gras_socket_close(rawIn);
238   gras_socket_close(rawOut);
239   return 1;
240 }
241
242 int amok_bw_cb_bw_request(gras_socket_t    expeditor,
243                           void            *payload) {return 1;}
244
245 int amok_bw_cb_sat_start(gras_socket_t     expeditor,
246                          void             *payload) {return 1;} 
247 int amok_bw_cb_sat_begin(gras_socket_t     expeditor,
248                          void             *payload) {return 1;}
249
250 #if 0
251 /* function to request a BW test between two external hosts */
252 gras_error_t grasbw_request(const char* from_name,unsigned int from_port,
253                            const char* to_name,unsigned int to_port,
254                            unsigned int bufSize,unsigned int expSize,unsigned int msgSize,
255                            /*OUT*/ double *sec, double*bw) {
256   
257   gras_sock_t *sock;
258   gras_msg_t *answer;
259   gras_error_t errcode;
260   /* The request */
261   BwExp_t *request;
262   msgHost_t *target;
263
264   if((errcode=gras_sock_client_open(from_name,from_port,&sock))) {
265     fprintf(stderr,"grasbw_request(): Error %s encountered while contacting the actuator\n",
266             gras_error_name(errcode));
267     return errcode;
268   }
269   if (!(request=(BwExp_t *)malloc(sizeof(BwExp_t))) ||
270       !(target=(msgHost_t*)malloc(sizeof(msgHost_t)))) {
271     fprintf(stderr,"grasbw_test(): Malloc error\n");
272     gras_sock_close(sock);
273     return malloc_error;    
274   }
275
276   request->bufSize=bufSize;
277   request->expSize=expSize;
278   request->msgSize=msgSize;
279   strcpy(target->host,to_name);
280   target->port=to_port;
281   
282   if ((errcode=gras_msg_new_and_send(sock,GRASMSG_BW_REQUEST, 2, 
283                               target,1,
284                               request,1))) {
285     fprintf(stderr,"grasbw_request(): Error %s encountered while sending the request.\n",
286             gras_error_name(errcode));
287     gras_sock_close(sock);
288     return errcode;
289   }
290   if ((errcode=gras_msg_wait(240,GRASMSG_BW_RESULT,&answer))) {
291     fprintf(stderr,"grasbw_request(): Error %s encountered while waiting for the answer.\n",
292             gras_error_name(errcode));
293     gras_sock_close(sock);
294     return errcode;
295   }
296
297   if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) {
298     fprintf(stderr,"grasbw_request(): Peer reported error %s (%s).\n",
299             gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg);
300     gras_msg_free(answer);
301     gras_sock_close(sock);
302     return errcode;
303   }
304
305   /*  fprintf(stderr,"sec=%p",gras_msg_ctn(answer,1,0,msgResult_t)); */
306   *sec=gras_msg_ctn(answer,1,0,msgResult_t).value;
307   *bw=gras_msg_ctn(answer,1,1,msgResult_t).value;
308
309   gras_msg_free(answer);
310   gras_sock_close(sock);
311   return no_error;
312 }
313
314 int grasbw_cbBWRequest(gras_msg_t *msg) {
315   /* specification of the test to run */
316   char* to_name=gras_msg_ctn(msg,0,0,msgHost_t).host;
317   unsigned int to_port=gras_msg_ctn(msg,0,0,msgHost_t).port;
318
319   unsigned int bufSize=gras_msg_ctn(msg,1,0,BwExp_t).bufSize;
320   unsigned int expSize=gras_msg_ctn(msg,1,0,BwExp_t).expSize;
321   unsigned int msgSize=gras_msg_ctn(msg,1,0,BwExp_t).msgSize;
322   /* our answer */
323   msgError_t *error;
324   msgResult_t *res;
325
326   if (!(error=(msgError_t *)malloc(sizeof(msgError_t))) ||
327       !(res=(msgResult_t *)malloc(sizeof(msgResult_t) * 2))) {
328     fprintf(stderr,"%s:%d:grasbw_cbRequest: Malloc error\n",__FILE__,__LINE__);
329     return malloc_error;    
330   }
331
332   if ((error->errcode=grasbw_test(to_name,to_port,bufSize,expSize,msgSize,
333                                   &(res[0].value),&(res[1].value) ))) {
334     fprintf(stderr,
335             "%s:%d:grasbw_cbRequest: Error %s encountered while doing the test\n",
336             __FILE__,__LINE__,gras_error_name(error->errcode));
337     strncpy(error->errmsg,"Error within grasbw_test",ERRMSG_LEN);
338     gras_msg_new_and_send(msg->sock,GRASMSG_BW_RESULT,2,
339                    error,1,
340                    res,2);
341     return 1;
342   }
343   res[0].timestamp = (unsigned int) gras_time();
344   res[1].timestamp = (unsigned int) gras_time();
345   gras_msg_new_and_send(msg->sock,GRASMSG_BW_RESULT,2,
346                  error,1,
347                  res,2);
348   gras_msg_free(msg);
349   return 1;
350 }
351
352 /* ***************************************************************************
353  * Link saturation
354  * ***************************************************************************/
355
356 gras_error_t grasbw_saturate_start(const char* from_name,unsigned int from_port,
357                                   const char* to_name,unsigned int to_port,
358                                   unsigned int msgSize, unsigned int timeout) {
359   gras_sock_t *sock;
360   gras_error_t errcode;
361   /* The request */
362   SatExp_t *request;
363   msgHost_t *target;
364   /* answer */
365   gras_msg_t *answer;
366
367   if((errcode=gras_sock_client_open(from_name,from_port,&sock))) {
368     fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while contacting peer\n",
369             __FILE__,__LINE__,gras_error_name(errcode));
370     return errcode;
371   }
372   if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t))) ||
373       !(target=(msgHost_t*)malloc(sizeof(msgHost_t)))) {
374     fprintf(stderr,"%s:%d:saturate_start(): Malloc error\n",__FILE__,__LINE__);
375     gras_sock_close(sock);
376     return malloc_error;    
377   }
378
379   request->timeout=timeout;
380   request->msgSize=msgSize;
381
382   strcpy(target->host,to_name);
383   target->port=to_port;
384
385   if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_START, 2, 
386                               target,1,
387                               request,1))) {
388     fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while sending the request.\n",
389             __FILE__,__LINE__,gras_error_name(errcode));
390     gras_sock_close(sock);
391     return errcode;
392   }
393   if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STARTED,&answer))) {
394     fprintf(stderr,"%s:%d:saturate_start(): Error %s encountered while waiting for the ACK.\n",
395             __FILE__,__LINE__,gras_error_name(errcode));
396     gras_sock_close(sock);
397     return errcode;
398   }
399
400   if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) {
401     fprintf(stderr,"%s:%d:saturate_start(): Peer reported error %s (%s).\n",
402             __FILE__,__LINE__,gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg);
403     gras_msg_free(answer);
404     gras_sock_close(sock);
405     return errcode;
406   }
407
408   gras_msg_free(answer);
409   gras_sock_close(sock);
410   return no_error;
411 }
412
413 int grasbw_cbSatStart(gras_msg_t *msg) {
414   gras_rawsock_t *raw;
415   gras_sock_t *sock;
416   gras_error_t errcode;
417   double start; /* time to timeout */
418
419   /* specification of the test to run */
420   char* to_name=gras_msg_ctn(msg,0,0,msgHost_t).host;
421   unsigned int to_port=gras_msg_ctn(msg,0,0,msgHost_t).port;
422
423   unsigned int msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize;
424   unsigned int timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout;
425   unsigned int raw_port;
426
427   /* The request */
428   SatExp_t *request;
429   /* answer */
430   gras_msg_t *answer;
431
432   /*
433   fprintf(stderr,"grasbw_cbSatStart(sd=%p)\n",msg->sock);
434   fprintf(stderr,"(server=%d,raw=%d,fromPID=%d,toPID=%d,toHost=%p,toPort=%d,toChan=%d)\n",
435           msg->sock->server_sock,msg->sock->raw_sock,msg->sock->from_PID,
436           msg->sock->to_PID,msg->sock->to_host,msg->sock->to_port,msg->sock->to_chan);
437   */
438
439   /* Negociate the saturation with the peer */
440   if((errcode=gras_sock_client_open(to_name,to_port,&sock))) {
441     fprintf(stderr,"cbSatStart(): Error %s encountered while contacting peer\n",
442             gras_error_name(errcode));
443     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
444                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
445                      errcode,"Cannot contact peer.\n");
446     return 1;
447   }
448   if (!(request=(SatExp_t *)malloc(sizeof(SatExp_t)))) {
449     fprintf(stderr,"cbSatStart(): Malloc error\n");
450     gras_sock_close(sock);
451     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
452                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
453                      malloc_error,"Cannot build request.\n");
454     return 1;    
455   }
456
457   request->timeout=gras_msg_ctn(msg,1,0,SatExp_t).timeout;
458   request->msgSize=gras_msg_ctn(msg,1,0,SatExp_t).msgSize;
459
460   if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_BEGIN, 1, 
461                               request,1))) {
462     fprintf(stderr,"cbSatStart(): Error %s encountered while sending the request.\n",
463             gras_error_name(errcode));
464     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
465                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
466                      errcode,"Cannot send request.\n");
467     gras_sock_close(sock);
468     return 1;
469   }
470
471   if ((errcode=gras_msg_wait(120,GRASMSG_SAT_BEGUN,&answer))) {
472     fprintf(stderr,"cbSatStart(): Error %s encountered while waiting for the ACK.\n",
473             gras_error_name(errcode));
474     gras_sock_close(sock);
475
476     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
477                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
478                      errcode,
479                      "Cannot receive the ACK.\n");
480     return 1;
481   }
482
483   if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) {
484     fprintf(stderr,"cbSatStart(): Peer reported error %s (%s).\n",
485             gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg);
486
487     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
488                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
489                      errcode,
490                      "Peer repported '%s'.\n",gras_msg_ctn(answer,0,0,msgError_t).errmsg);
491     gras_msg_free(answer);
492     gras_sock_close(sock);
493     return 1;
494   }
495
496   raw_port=gras_msg_ctn(answer,1,0,SatExp_t).port;
497
498   if ((errcode=gras_rawsock_client_open(to_name,raw_port,msgSize,&raw))) {
499     fprintf(stderr,"cbSatStart(): Error %s while opening raw socket to %s:%d.\n",
500             gras_error_name(errcode),to_name,gras_msg_ctn(answer,1,0,SatExp_t).port);
501
502     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
503                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
504                      errcode,"Cannot open raw socket.\n");
505     gras_sock_close(sock);
506     return 1;
507   }
508
509   /* send a train of data before repporting that XP is started */
510   if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) {
511     fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode));
512     grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
513                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
514                      errcode,"Cannot raw send.\n");
515     gras_sock_close(sock);
516     gras_rawsock_close(raw);
517     return 1;
518   }
519   
520   grasRepportError(msg->sock,GRASMSG_SAT_STARTED,1,
521                    "cbSatStart: Severe error: Cannot send error status to requester!!\n",
522                    no_error,"Saturation started");
523   gras_msg_free(answer);
524   gras_msg_free(msg);
525   
526   /* Do the saturation until we get a SAT_STOP message or until we timeout the whole XP*/
527   start=gras_time();
528   while (gras_msg_wait(0,GRASMSG_SAT_STOP,&msg)==timeout_error && 
529          gras_time()-start < timeout) {
530     if ((errcode=gras_rawsock_send(raw,msgSize,msgSize))) {
531       fprintf(stderr,"cbSatStart: Failure %s during raw send\n",gras_error_name(errcode));
532       /* our error message do not interess anyone. SAT_STOP will do nothing. */
533       gras_sock_close(sock);
534       gras_rawsock_close(raw);
535       return 1;
536     } 
537   }
538   if (gras_time()-start > timeout) {
539     fprintf(stderr,"The saturation experiment did timeout. Stop it NOW\n");
540     gras_sock_close(sock);
541     gras_rawsock_close(raw);
542     return 1;
543   }
544
545   /* Handle the SAT_STOP which broke the previous while */
546   
547   if ((errcode=gras_msg_new_and_send(sock, GRASMSG_SAT_END,0))) {
548     fprintf(stderr,"cbSatStart(): Cannot tell peer to stop saturation\n");
549
550     grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1,
551                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
552                      errcode,"Sending SAT_END to peer failed.\n");
553     gras_sock_close(sock);
554     gras_rawsock_close(raw);
555     return 1;
556   }
557   
558   if ((errcode=gras_msg_wait(60,GRASMSG_SAT_ENDED,&answer))) {
559     fprintf(stderr,"cbSatStart(): Peer didn't ACK the end\n");
560
561     grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1,
562                      "cbSatStart: Severe error: Cannot send error status to requester!!\n",
563                      errcode,"Receiving SAT_ENDED from peer failed.\n");
564     gras_sock_close(sock);
565     gras_rawsock_close(raw);
566     return 1;
567   }
568   grasRepportError(msg->sock,GRASMSG_SAT_STOPPED,1,
569                    "cbSatStart: Severe error: Cannot send error status to requester!!\n",
570                    no_error,"");
571
572   gras_sock_close(sock);
573   gras_rawsock_close(raw);
574   gras_msg_free(answer);
575   gras_msg_free(msg);
576
577   return 1;  
578 }
579
580 int grasbw_cbSatBegin(gras_msg_t *msg) {
581   gras_rawsock_t *raw;
582   gras_error_t errcode;
583   double start; /* timer */
584   /* request */
585   unsigned int msgSize=gras_msg_ctn(msg,0,0,SatExp_t).msgSize;
586   unsigned int timeout=gras_msg_ctn(msg,0,0,SatExp_t).timeout;
587   /* answer */
588   SatExp_t *request;
589   msgError_t *error;
590
591   if (!(request=(SatExp_t*)malloc(sizeof(SatExp_t))) ||
592       !(error=(msgError_t *)malloc(sizeof(msgError_t)))) {
593     fprintf(stderr,"cbSatBegin(): Malloc error\n");
594     grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2,
595                      "cbSatBegin: Severe error: Cannot send error status to requester!!\n",
596                      malloc_error,"Malloc error");
597     return 1;
598   }
599
600   if ((errcode=gras_rawsock_server_open(6666,8000,msgSize,&raw))) { 
601     fprintf(stderr,"cbSatBegin(): Error %s encountered while opening a raw socket\n",
602             gras_error_name(errcode));
603     grasRepportError(msg->sock,GRASMSG_SAT_BEGUN,2,
604                      "cbSatBegin: Severe error: Cannot send error status to requester!!\n",
605                      errcode,"Cannot open raw socket");
606     return 1;
607   }
608   request->port=gras_rawsock_get_peer_port(raw);
609   request->msgSize=msgSize;
610   error->errcode=no_error;
611   error->errmsg[0]='\0';
612   if ((errcode=gras_msg_new_and_send(msg->sock,GRASMSG_SAT_BEGUN,2,
613                               error,1,
614                               request,1))) {
615     fprintf(stderr,"cbSatBegin(): Error %s encountered while send ACK to peer\n",
616             gras_error_name(errcode));
617     return 1;
618   }
619   gras_msg_free(msg);
620
621   start=gras_time();
622   while (gras_msg_wait(0,GRASMSG_SAT_END,&msg)==timeout_error &&
623          gras_time() - start < timeout) {
624     errcode=gras_rawsock_recv(raw,msgSize,msgSize,1);
625     if (errcode != timeout_error && errcode != no_error) {
626       fprintf(stderr,"cbSatBegin: Failure %s during raw receive\n",gras_error_name(errcode));
627       /* our error message do not interess anyone. SAT_END will do nothing. */
628       /* (if timeout'ed, it may be because the sender stopped emission. so survive it) */
629       return 1;
630     } 
631   }
632   if (gras_time()-start > timeout) {
633     fprintf(stderr,"The saturation experiment did timeout. Stop it NOW.\n");
634     gras_rawsock_close(raw);
635     return 1;
636   }
637
638   grasRepportError(msg->sock,GRASMSG_SAT_ENDED,1,
639                    "cbSatBegin: Cannot send SAT_ENDED.\n",
640                    no_error,"");
641   gras_rawsock_close(raw);
642   gras_msg_free(msg);
643   return 1;
644 }
645
646 gras_error_t grasbw_saturate_stop(const char* from_name,unsigned int from_port,
647                                  const char* to_name,unsigned int to_port) {
648   gras_error_t errcode;
649   gras_sock_t *sock;
650   gras_msg_t *answer;
651
652   if((errcode=gras_sock_client_open(from_name,from_port,&sock))) {
653     fprintf(stderr,"saturate_stop(): Error %s encountered while contacting peer\n",
654             gras_error_name(errcode));
655     return errcode;
656   }
657
658   if ((errcode=gras_msg_new_and_send(sock,GRASMSG_SAT_STOP,0))) {
659     fprintf(stderr,"saturate_stop(): Error %s encountered while sending request\n",
660             gras_error_name(errcode));
661     gras_sock_close(sock);
662     return errcode;
663   }
664
665   if ((errcode=gras_msg_wait(120,GRASMSG_SAT_STOPPED,&answer))) {
666     fprintf(stderr,"saturate_stop(): Error %s encountered while receiving ACK\n",
667             gras_error_name(errcode));
668     gras_sock_close(sock);
669     return errcode;
670   }
671
672   if((errcode=gras_msg_ctn(answer,0,0,msgError_t).errcode)) {
673     fprintf(stderr,"saturate_stop(): Peer reported error %s (%s).\n",
674             gras_error_name(errcode),gras_msg_ctn(answer,0,0,msgError_t).errmsg);
675     gras_msg_free(answer);
676     gras_sock_close(sock);
677     return errcode;
678   }
679
680   gras_msg_free(answer);
681   gras_sock_close(sock);
682
683   return no_error;
684 }
685 #endif