Wiselib
|
00001 #ifndef _KEYLEVELS_MAIN_H 00002 #define _KEYLEVELS_MAIN_H 00003 00004 // maximal connectivity (key-wise) that can be reached by a node 00005 #define NODES_MAX 50 00006 00007 #define WAIT_FOR_ROUTING 20000 00008 00009 #include "util/serialization/simple_types.h" 00010 #include "util/base_classes/radio_base.h" 00011 00012 #include "keylevels_message.h" 00013 #include "keylevels_share.h" 00014 #include "ttl_flooding.h" 00015 00016 namespace wiselib { 00017 00018 template<typename OsModel_P, 00019 typename Radio_P, 00020 typename Routing_P, 00021 typename Crypto_P, 00022 typename Clustering_P, 00023 typename Debug_P = typename OsModel_P::Debug, 00024 typename Timer_P = typename OsModel_P::Timer, 00025 typename Random_P = typename OsModel_P::Rand> 00026 class Keylevels: public RadioBase<OsModel_P, typename Radio_P::node_id_t, 00027 typename Radio_P::size_t, typename Radio_P::block_data_t> { 00028 public: 00029 typedef OsModel_P OsModel; 00030 typedef Radio_P Radio; 00031 typedef Routing_P Routing; 00032 typedef Crypto_P Crypto; 00033 typedef Debug_P Debug; 00034 typedef Timer_P Timer; 00035 typedef Random_P Random; 00036 typedef Clustering_P Clustering; 00037 00038 typedef Keylevels<OsModel, Radio, Routing, Crypto, Clustering, Debug, Timer, Random> self_type; 00039 typedef self_type* self_pointer_t; 00040 00041 typedef typename Radio::node_id_t node_id_t; 00042 typedef typename Radio::size_t size_t; 00043 typedef typename Radio::block_data_t block_data_t; 00044 typedef typename Radio::message_id_t message_id_t; 00045 00046 typedef KeylevelsMessage<OsModel, Radio> KeylevelMessage; 00047 00048 typedef KeyShare<OsModel, Radio> keyshare_t; 00049 typedef TTLFlooding<OsModel, Radio, Debug, NODES_MAX> radio_ttl_t; 00050 00051 enum ReturnValues { 00052 SUCCESS = OsModel::SUCCESS 00053 }; 00054 00055 Keylevels() 00056 { 00057 keyOfferMsgCnt_in = 0; 00058 keyOfferMsgCnt_out = 0; 00059 groupKeyMsgCnt_in = 0; 00060 groupKeyMsgCnt_out = 0; 00061 neighborMsgCnt_in = 0; 00062 neighborMsgCnt_out = 0; 00063 } 00064 00065 int init(Radio& radio, Routing& routing, Crypto& crypto, Clustering& clustering, Debug& debug, 00066 Timer& timer, Random& random) { 00067 radio_ = &radio; 00068 routing_ = &routing; 00069 crypto_ = &crypto; 00070 debug_ = &debug; 00071 timer_ = &timer; 00072 random_ = &random; 00073 clustering_ = &clustering; 00074 if ( clustering_->cluster_head() ) 00075 { 00076 debug_->debug("[KL] {%d} leader\n", radio_->id()); 00077 group_key_.leader_init(random_); 00078 } 00079 else 00080 { 00081 debug_->debug("[KL] {%d} not a leader\n", radio_->id()); 00082 group_key_.init(random_); 00083 } 00084 00085 keyshare_.init(*radio_, *debug_, *random_); 00086 00087 #ifdef KEYLEVELS_DEBUG 00088 keyshare_.listKeyshare(); 00089 #endif 00090 00091 routing_->template reg_recv_callback<self_type, 00092 &self_type::message_received> (this); 00093 00094 /* 00095 * PTB: odkomentuj init_ttl_op() zakomentuj timer_-> ... zeby wylaczyc czekanie na sasiadow 00096 */ 00097 /* 00098 have_neighbors = true; 00099 timer_->template set_timer<self_type, 00100 &self_type::init_ttl_op> (10, this, 0); 00101 */ 00102 timer_->template set_timer<self_type, 00103 &self_type::start_neighbor_seek_init> (10, this, 0); 00104 00105 return SUCCESS; 00106 } 00107 00108 00109 /* prepare neighborhood discovery */ 00110 void start_neighbor_seek_init(void*) { 00111 have_neighbors = false; 00112 radio_->template reg_recv_callback<self_type, &self_type::neighbor_message_received> (this); 00113 start_neighbor_seek(this); 00114 } 00115 00116 void neighbor_message_received(node_id_t from, size_t size, 00117 block_data_t* data) { 00118 KeylevelMessage* message = (KeylevelMessage *) data; 00119 show_keylevels_message(message,0); 00120 if (message->message_type() == NEIGHBORHOOD_ACK) { 00121 #ifdef KEYLEVELS_DEBUG 00122 debug_->debug("[KL] {%d} received NEIGHBORHOOD_ACK from %d\n", radio_->id(), from); 00123 #endif 00124 // counting --------------------------------------------- 00125 neighborMsgCnt_in++; 00126 if (have_neighbors) { 00127 return; 00128 } 00129 have_neighbors = true; 00130 init_ttl_op(); 00131 } else if (message->message_type() == NEIGHBORHOOD_SEEK) { 00132 if (from != radio_->id()) { 00133 #ifdef KEYLEVELS_DEBUG 00134 debug_->debug("[KL] {%d} sending NEIGHBORHOOD_ACK to %d\n", radio_->id(), from); 00135 #endif 00136 KeylevelMessage msg; 00137 msg.set_message_type(NEIGHBORHOOD_ACK); 00138 msg.set_source(radio_->id()); 00139 msg.set_destination(from); 00140 msg.set_payload(0, NULL); 00141 show_keylevels_message(&msg, 1); 00142 radio_->send(from, msg.buffer_size(), (block_data_t*) &msg); 00143 // counting --------------------------------------------- 00144 neighborMsgCnt_out++; 00145 if (have_neighbors) { 00146 return; 00147 } 00148 have_neighbors = true; 00149 init_ttl_op(); 00150 } 00151 } 00152 } 00153 00154 /* do neighbor discovery */ 00155 void start_neighbor_seek(void*) 00156 { 00157 if (have_neighbors) { return; } // okay, we've already got someone to talk to 00158 00159 /* prepare neighbor seek message and send it; go to sleep waiting for response */ 00160 #ifdef KEYLEVELS_DEBUG 00161 debug_->debug("[KL] {%d} broadcasting NEIGHBORHOOD_SEEK\n", radio_->id()); 00162 #endif 00163 KeylevelMessage message; 00164 message.set_message_type(NEIGHBORHOOD_SEEK); 00165 message.set_source(radio_->id()); 00166 message.set_destination(radio_->BROADCAST_ADDRESS); 00167 message.set_payload(0, NULL); 00168 show_keylevels_message(&message,1); 00169 radio_->send(radio_->BROADCAST_ADDRESS, message.buffer_size(),(block_data_t*) &message); 00170 // counting --------------------------------------------- 00171 neighborMsgCnt_out++; 00172 timer_->template set_timer<self_type, &self_type::start_neighbor_seek> ( 00173 15000, this, 0); 00174 } 00175 00176 void init_ttl_op() 00177 { 00178 // PTB: added launching via timer 00179 //init_ttl_op(NULL); 00180 timer_->template set_timer<self_type, &self_type::init_ttl_op> ( 5, this, 0 ); 00181 } 00182 00183 /* run this after a neighbor is found */ 00184 void init_ttl_op(void*) 00185 { 00186 ttl_.init(*radio_, *debug_); 00187 ttl_.set_notify_all_on_path(true); 00188 ttl_.enable_radio(); 00189 ttl_.template reg_recv_callback<self_type, 00190 &self_type::key_offer_received> (this); 00191 timer_->template set_timer<self_type, &self_type::seek_for_group_key> ( 00192 WAIT_FOR_ROUTING, this, 0); 00193 } 00194 00195 void seek_for_group_key(void*) 00196 { 00197 if (!group_key_found()) 00198 { 00199 increase_seek_ttl(); 00200 00201 #ifdef KEYLEVELS_DEBUG 00202 debug_->debug("[KL] {%d} seeking for group key with TTL = %d\n", radio_->id(), ttl_.get_ttl()); 00203 #endif 00204 00205 broadcast_all_keys_with_ttl(); 00206 00207 timer_->template set_timer<self_type, 00208 &self_type::seek_for_group_key> ( 00209 get_current_seek_timeout(), this, 0); 00210 } 00211 } 00212 00213 group_key* get_group_key() 00214 { 00215 if (group_key_.have_key) 00216 return &group_key_; 00217 00218 return NULL; 00219 } 00220 00221 inline int get_current_seek_timeout() 00222 { 00223 return (3 * get_current_ttl() * 1000) + 2000; 00224 } 00225 00226 inline int get_current_ttl() 00227 { 00228 return ttl_.get_ttl(); 00229 } 00230 00231 inline void increase_seek_ttl() 00232 { 00233 return ttl_.set_ttl(ttl_.get_ttl() + 1); 00234 } 00235 00236 inline bool group_key_found() 00237 { 00238 return group_key_.have_key; 00239 } 00240 00241 void enable_radio() { radio_->enable_radio(); } 00242 00243 void disable_radio() 00244 { } 00245 00246 void broadcast_all_keys_with_ttl() 00247 { 00248 for (unsigned int i = 0; i < keyshare_.get_keyshare_size(); ++i) 00249 { 00250 key_info x; 00251 x.key_index = keyshare_.keyshare[i].key_index; 00252 x.key_level = keyshare_.keyshare[i].key_level; 00253 ttl_.send(1000 * ttl_.get_ttl() + 100 * radio_->id() + x.key_index, 00254 sizeof(key_info), (block_data_t*) &x); 00255 // counting --------------------------------------------- 00256 keyOfferMsgCnt_out++; 00257 #ifdef KEYLEVELS_DEBUG 00258 debug_->debug("[KL] {%d} sending key offer (%d,%d) with MSG_ID = %d\n", 00259 radio_->id(), 00260 x.key_index, 00261 x.key_level, 00262 1000*ttl_.get_ttl()+100*radio_->id()+x.key_index 00263 ); 00264 #endif 00265 } 00266 } 00267 00268 void send_group_key_to_all_trusted_neighbors() 00269 { 00270 for (node_id_t i = 0; i < NODES_MAX; i++) 00271 { 00272 key* pairwise_key = keyshare_.get_key_info(i); 00273 00274 if (pairwise_key != NULL) 00275 { 00276 //TODO this can return false if no route to $i'th node available 00277 send_group_key(i); 00278 // counting --------------------------------------------- 00279 groupKeyMsgCnt_out++; 00280 } 00281 } 00282 } 00283 00284 /* builds a KEY_ACK message and tries to send it to $receiver 00285 * @return true if message was properly routed 00286 * false if routing does not reach $receiver 00287 */ 00288 bool send_key_ack(node_id_t receiver, key_info* key_info) 00289 { 00290 #ifdef KEYLEVELS_DEBUG 00291 debug_->debug("[KL] {%d} sending ACK (%d,%d) to node %d\n", 00292 radio_->id(), 00293 key_info->key_index, 00294 key_info->key_level, 00295 receiver 00296 ); 00297 #endif 00298 00299 KeylevelMessage message; 00300 message.set_message_type(KEY_ACK); 00301 message.set_source(radio_->id()); 00302 message.set_destination(receiver); 00303 message.set_payload(sizeof(key_info), (block_data_t*) key_info); 00304 show_keylevels_message(&message,1); 00305 00306 // check if we can route msg to $receiver 00307 if(Routing::SUCCESS != routing_->send(receiver, message.buffer_size(), 00308 (block_data_t*) &message)) 00309 return false; 00310 // counting --------------------------------------------- 00311 keyOfferMsgCnt_out++; 00312 return true; 00313 } 00314 00315 bool send_group_key(node_id_t receiver) 00316 { 00317 #ifdef KEYLEVELS_DEBUG 00318 debug_->debug("[KL] {%d} sending group key to node %d\n", radio_->id(), receiver); 00319 #endif 00320 00321 KeylevelMessage message; 00322 message.set_message_type(GROUP_KEY); 00323 message.set_source(radio_->id()); 00324 message.set_destination(receiver); 00325 uint8_t enc_key_data[GROUP_KEY_SIZE]; 00326 crypto_->enable(); 00327 crypto_->key_setup(SMALL_KEY_SIZE * 8, 00328 keyshare_.get_key_info(receiver)->key_value); 00329 crypto_->encrypt(group_key_.key_data, enc_key_data); 00330 message.set_payload(sizeof(enc_key_data),(block_data_t*) (enc_key_data)); 00331 show_keylevels_message(&message,1); 00332 if(Routing::SUCCESS != routing_->send(receiver, message.buffer_size(),(block_data_t*) &message)) 00333 { 00334 return false; 00335 } 00336 // counting --------------------------------------------- 00337 groupKeyMsgCnt_out++; 00338 return true; 00339 } 00340 00341 void message_received(node_id_t from, size_t size, block_data_t* data) 00342 { 00343 KeylevelMessage* message = (KeylevelMessage *) data; 00344 show_keylevels_message(message,0); 00345 if (message->message_type() == KEY_ACK) 00346 { 00347 #ifdef KEYLEVELS_DEBUG 00348 debug_->debug("[KL] {%d} received KEY_ACK from %d\n", radio_->id(), from); 00349 #endif 00350 // counting --------------------------------------------- 00351 keyOfferMsgCnt_in++; 00352 key_info* key_ack = (key_info*) message->payload(); 00353 key k; 00354 k.key_index = key_ack->key_index; 00355 memcpy(k.key_value, 00356 keyshare_.get_key(key_ack->key_index)->key_value, 00357 SMALL_KEY_SIZE); 00358 int ld = key_ack->key_level 00359 - keyshare_.get_key(key_ack->key_index)->key_level; 00360 if (ld >= 0) 00361 { 00362 k.key_level = key_ack->key_level; 00363 for (int i = 0; i < ld; i++) 00364 keyshare_.variation_on_SDBMHash(k.key_value, SMALL_KEY_SIZE); 00365 } 00366 else 00367 { 00368 k.key_level = keyshare_.get_key(key_ack->key_index)->key_level; 00369 } 00370 store_new_trusted_link(from, &k); 00371 00372 } 00373 else if (message->message_type() == GROUP_KEY) 00374 { 00375 #ifdef KEYLEVELS_DEBUG 00376 debug_->debug("[KL] {%d} received GROUP_KEY message from %d: ", radio_->id(), from); 00377 #endif 00378 // counting --------------------------------------------- 00379 groupKeyMsgCnt_in++; 00380 uint8_t dec_key_data[SMALL_KEY_SIZE]; 00381 uint8_t* enc_key_data; 00382 enc_key_data = (uint8_t*) message->payload(); 00383 crypto_->enable(); 00384 crypto_->key_setup(SMALL_KEY_SIZE * 8, 00385 (uint8_t*) keyshare_.get_key_info(from)->key_value); 00386 00387 crypto_->decrypt(enc_key_data, dec_key_data); 00388 00389 if (!group_key_.have_key) 00390 { 00391 group_key_.set_key(dec_key_data); 00392 #ifdef KEYLEVELS_DEBUG 00393 print_key_value(group_key_.key_data, GROUP_KEY_SIZE); 00394 #endif 00395 send_group_key_to_all_trusted_neighbors(); 00396 00397 notify_receivers(0, (size_t) GROUP_KEY_SIZE, 00398 (block_data_t*) &(group_key_.key_data)); 00399 } 00400 } 00401 else 00402 { 00403 #ifdef KEYLEVELS_DEBUG 00404 debug_->debug("[KL] {%d} message_received: received UNKNOWN message from %d\n", 00405 radio_->id(), 00406 from); 00407 #endif 00408 } 00409 } 00410 00411 void key_offer_received(node_id_t from, size_t size, block_data_t* data) 00412 { 00413 #ifdef KEYLEVELS_DEBUG 00414 debug_->debug("[KL] {%d} received key offer from Node %d", radio_->id(), from); 00415 #endif 00416 // counting --------------------------------------------- 00417 keyOfferMsgCnt_in++; 00418 key_info key_offer_o, *key_offer; 00419 key_offer = &key_offer_o; 00420 memcpy(key_offer, data, size); 00421 00422 if (keyshare_.owns_key(key_offer->key_index)) 00423 { 00424 #ifdef KEYLEVELS_DEBUG 00425 debug_->debug("[KL] {%d} found common key with Node %d (%d,%d):(%d,%d)\n", 00426 radio_->id(), 00427 from, 00428 keyshare_.get_key(key_offer->key_index)->key_index, 00429 keyshare_.get_key(key_offer->key_index)->key_level, 00430 key_offer->key_index, 00431 key_offer->key_level 00432 ); 00433 #endif 00434 key k; 00435 k.key_index = key_offer->key_index; 00436 memcpy(k.key_value, 00437 keyshare_.get_key(key_offer->key_index)->key_value, 00438 SMALL_KEY_SIZE); 00439 int ld = key_offer->key_level - keyshare_.get_key( 00440 key_offer->key_index)->key_level; 00441 if (ld >= 0) 00442 { 00443 k.key_level = key_offer->key_level; 00444 for (int i = 0; i < ld; i++) 00445 { 00446 keyshare_.variation_on_SDBMHash(k.key_value, SMALL_KEY_SIZE); 00447 } 00448 } 00449 else 00450 { 00451 k.key_level = keyshare_.get_key(key_offer->key_index)->key_level; 00452 } 00453 key_info key_ack; 00454 key_ack.key_index = k.key_index; 00455 key_ack.key_level = k.key_level; 00456 // check if sending ACK is possible, abort if not [PTB] 00457 if(!send_key_ack(from, &key_ack)) 00458 { 00459 return; 00460 } 00461 // okay, ACK sent, assume we have link with $from [PTB] 00462 store_new_trusted_link(from, &k); 00463 if (group_key_found()) 00464 { 00465 //TODO this can return false if no route to $from available [PTB] 00466 if(!send_group_key(from)) 00467 { } 00468 } 00469 } 00470 } 00471 00472 void store_new_trusted_link(node_id_t node, key* key) 00473 { 00474 if (!keyshare_.trusted_link_exists(node)) 00475 { 00476 #ifdef KEYLEVELS_DEBUG 00477 debug_->debug("[KL] {%d} established new secure link with Node %d\n", radio_->id(), node); 00478 #endif 00479 keyshare_.put_trusted_link(node, *key); 00480 } 00481 else 00482 { 00483 if (key->key_index < keyshare_.get_key_info(node)->key_index) 00484 { 00485 keyshare_.put_trusted_link(node, *key); 00486 } 00487 } 00488 } 00489 00490 void print_key_value(uint8_t* value, uint8_t size) 00491 { 00492 for (int i = 0; i < size; i++) 00493 { 00494 debug_->debug("%d:", value[i]); 00495 } 00496 debug_->debug("\n"); 00497 } 00498 00499 void print_all_key_info(key* k) 00500 { 00501 debug_->debug("[KL] {%d} KEY: (%d,%d) ", radio_->id(), k->key_index, k->key_level); 00502 print_key_value(k->key_value, SMALL_KEY_SIZE); 00503 } 00504 00505 void show_keylevels_message(KeylevelMessage* msg, int dir) 00506 { 00507 #ifndef KL_EXTREME 00508 return; 00509 #endif 00510 uint8_t* temp = (uint8_t*) msg; 00511 if(dir) 00512 debug_->debug("[KL] {%d} outgoing kl message[0]: [%d]", radio_->id(), temp[0]); 00513 else 00514 debug_->debug("[KL] {%d} incoming kl message[0]: [%d]", radio_->id(), temp[0]); 00515 return; 00516 00517 debug_->debug("["); 00518 int i=0; 00519 for(i=0;i<msg->buffer_size();i++){ 00520 debug_->debug("%d, ",temp[i]); 00521 } 00522 debug_->debug("]"); 00523 } 00524 // --------- access functions for stat fields [PTB] ----------------------------- 00525 int getNeighMsgCnt_in() { return neighborMsgCnt_in; } 00526 int getNeighMsgCnt_out() { return neighborMsgCnt_out; } 00527 int getKeyOfferMsgCnt_in() { return keyOfferMsgCnt_in; } 00528 int getKeyOfferMsgCnt_out(){ return keyOfferMsgCnt_out; } 00529 int getGroupKeyMsgCnt_in() { return groupKeyMsgCnt_in; } 00530 int getGroupKeyMsgCnt_out(){ return groupKeyMsgCnt_out; } 00531 00532 private: 00533 typename Radio::self_pointer_t radio_; 00534 typename Debug::self_pointer_t debug_; 00535 typename Timer::self_pointer_t timer_; 00536 typename Routing::self_pointer_t routing_; 00537 typename Random::self_pointer_t random_; 00538 00539 keyshare_t keyshare_; 00540 group_key group_key_; 00541 Crypto* crypto_; 00542 Clustering* clustering_; 00543 00544 radio_ttl_t ttl_; 00545 00546 bool have_neighbors; 00547 //------------ fields for stats [PTB] ------------------------------------------- 00548 int neighborMsgCnt_in, neighborMsgCnt_out; // messages for seeking neighbors 00549 int keyOfferMsgCnt_in, keyOfferMsgCnt_out; // messages with key offer 00550 int groupKeyMsgCnt_in, groupKeyMsgCnt_out; // messages referring to groupkey 00551 }; 00552 00553 } /* namespace wiselib */ 00554 00555 #endif /* _KEYLEVELS_MAIN_H */