Fast Probing
 All Classes Files Functions Variables Typedefs Macros
/home/aomegax/workspace/Fast Probing/mt-main.cpp
Go to the documentation of this file.
1 /*
2  * Fast Probing - An Active Probing Library for IP Options Equipped probes (http://traffic.comics.unina.it/)
3  *
4  * Copyright : (C) 2012 by Pietro Marchetta, Walter de Donato, Francesco Cesareo,
5  * Antonio Pescape' (PI)
6  * of the COMICS (COMputer for Interaction and
7  * CommunicationS) Group, Dipartimento di Informatica
8  * e Sistemistica of the University of Napoli "Federico II".
9  *
10  * email : pietro.marchetta@unina.it , walter.dedonato@unina.it , cesareo.francesco@gmail.com
11  * pescape@unina.it
12  *
13  * This program is free software: you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation, either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program. If not, see <http://www.gnu.org/licenses/>.
25  *
26  */
27 
28 #include "lib/fastprobing.h"
29 #include "lib/probereply.h"
30 #include "lib/generaloption.h"
31 #include "lib/util.h"
32 
33 #include <iostream>
34 #include <string.h>
35 #include <semaphore.h>
36 #include <pthread.h>
37 #include <list>
38 
39 sem_t mainsem;
40 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
41 
42 typedef struct LocalOptions
43 {
44  std::string* dst_addr;
46 
48 
49 void* send_probe(void* lOpts);
50 
51 int main()
52 {
53  std::cout << "Hello Fast Probing - multithread!" << std::endl;
54 
55  // create a common udp socket
56  int socketudp;
57  if ((socketudp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
58  {
59  perror("General UDP socket - socket");
60  close(socketudp);
61  exit(1);
62  }
63 
64  // enable address reuse
65  int on = 1;
66  int status = 0;
67 
68  int ttl = 255; // set ttl
69  int src_port = 34567; // set source port number
70 
71 
72  if ((status == setsockopt(socketudp, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl))) < 0)
73  {
74  perror("General UDP socket - setsockopt");
75  close(socketudp);
76  exit(1);
77  }
78 
79  if ((status == setsockopt(socketudp, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0)
80  {
81  perror("General UDP socket - setsockopt");
82  close(socketudp);
83  exit(1);
84  }
85 
86  // set source address
87  struct sockaddr_in src_addr;
88  src_addr.sin_family = AF_INET;
89  src_addr.sin_addr.s_addr = htonl(INADDR_ANY);
90  src_addr.sin_port = htons(src_port);
91 
92  if (bind(socketudp, (struct sockaddr *)&src_addr, sizeof(src_addr))<0)
93  perror("General UDP socket - bind");
94 
95 
96  // instantiation
97  GeneralOption *option = new GeneralOption(socketudp, lock);
98 
99  // setting options campaing
100  option->set_verbose_mode(true); // enable verbose mode
101  option->set_retries(2); // set to 2 the retry number to obtain response probe
102  option->set_timeout(2000); // set time to wait response
103  option->set_src_port(src_port); // set source port number
104  option->set_ttl(ttl); // set ttl
105 
106  // set destination IPs
107  std::list<std::string> ips;
108 
109  ips.push_back("10.0.12.20");
110  ips.push_back("10.0.12.40");
111  ips.push_back("10.0.12.60");
112  ips.push_back("10.0.12.80");
113  ips.push_back("10.0.12.100");
114 
115  int thread_number = 5; // number of concurrent thread
116  int current_thread = 0;
117 
118  std::cout << "Main semaphore initialized to " << thread_number << std::endl;
119 
120  sem_init(&mainsem, 0, thread_number);
121 
122  while (!ips.empty())
123  {
124  // acquire token on semaphore
125  sem_wait(&mainsem);
126 
127  pthread_t pth;
128 
129  LocalOptions lOpts;
130 
131  // get an IP address from IPs list
132  lOpts.dst_addr = new std::string(ips.front());
133  ips.pop_front();
134 
135  lOpts.gOpts = option;
136 
137  std::cout << "Creating thread " << current_thread+1 << " for IP [" << *lOpts.dst_addr << "]" << std::endl;
138 
139  void* pointer = malloc(sizeof(lOpts)); // pointer to attributes for current thread
140  if (pointer == NULL)
141  {
142  while (true)
143  {
144  std::cout << "ERROR: main thread malloc returned null" << std::endl;
145  pointer = malloc(sizeof(lOpts));
146 
147  if (pointer == NULL)
148  continue;
149  }
150  break;
151  }
152 
153  memcpy(pointer, (void*) &lOpts, sizeof(lOpts));
154 
155  while (true)
156  {
157  // create new thread executing send_probe function
158  int rc = pthread_create(&pth, NULL, send_probe, pointer);
159 
160  if (rc)
161  {
162  std::cout << "ERROR: return code from pthread_create() is " << rc << std::endl;
163  continue;
164  }
165  break;
166  }
167  current_thread++; // increase current thread number;
168  }
169 
170  sem_destroy(&mainsem);
171  pthread_detach(pthread_self());
172  pthread_exit(NULL);
173 
174  delete option;
175 
176  return 0;
177 }
178 
179 void* send_probe (void *lOpts)
180 {
181  LocalOptions* option = (LocalOptions*) lOpts;
182 
183  // instantiation
184  FastProbing *probe = new FastProbing();
185  ProbeReply *reply = new ProbeReply();
186 
187  // send UDP probe to dst_addr
188  probe->udp(option->gOpts, reply, *option->dst_addr);
189 
190  pthread_mutex_lock(&lock);
191 
192  // print details if a response probe is received
193  if (reply->has_response())
194  reply->print();
195  else
196  std::cout << "No response obtained from " << *option->dst_addr << std::endl;
197 
198  pthread_mutex_unlock(&lock);
199 
200  delete option;
201  // release token on semaphore
202  sem_post(&mainsem);
203  pthread_detach(pthread_self());
204  pthread_exit(NULL);
205 }