00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _WIN32
00036 #include <sys/socket.h>
00037 #include <arpa/inet.h>
00038 #include <netinet/in.h>
00039 #include <netdb.h>
00040 #include <sys/un.h>
00041 #include <unistd.h>
00042 #include <sys/time.h>
00043 #include <netdb.h>
00044 #include <pthread.h>
00045 #include "config.h"
00046 #if HAVE_LIBBLUETOOTH
00047 #ifdef _WIN32
00048 #include <Ws2bth.h>
00049 #else
00050 #include <bluetooth/bluetooth.h>
00051 #include <bluetooth/rfcomm.h>
00052 #endif
00053 #endif
00054
00055 #else
00056 #include <winsock2.h>
00057 #include <windows.h>
00058 #include <time.h>
00059 #include "winconfig.h"
00060 #endif
00061
00062 #include <stdlib.h>
00063 #include "include/acc.h"
00064 #include "include/connection.h"
00065 #include "include/data_structures.h"
00066 #include "include/macros.h"
00067 #include "include/mc_error.h"
00068 #include "include/mc_platform.h"
00069 #include "include/message.h"
00070 #include "include/mtp_http.h"
00071 #include "include/xml_parser.h"
00072 #include "include/fipa_acl_envelope.h"
00073
00074 #define BACKLOG 200
00075
00076 acc_p
00077 acc_Initialize(struct mc_platform_s* mc_platform)
00078 {
00079 acc_p acc;
00080 acc = (acc_p)malloc(sizeof(acc_t));
00081 acc->mc_platform = mc_platform;
00082
00083 acc->waiting = 0;
00084 acc->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00085 MUTEX_INIT(acc->waiting_lock);
00086 acc->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00087 COND_INIT(acc->waiting_cond);
00088
00089
00090 MUTEX_INIT(&acc->conn_thread_lock);
00091 COND_INIT(&acc->conn_thread_cond);
00092 acc->num_conn_threads = 0;
00093
00094
00095 MUTEX_INIT(&acc->msg_thread_lock);
00096 COND_INIT(&acc->msg_thread_cond);
00097 acc->num_msg_threads = 0;
00098 return acc;
00099 }
00100
00101 int
00102 acc_Destroy(acc_p acc)
00103 {
00104 if(acc == NULL) {
00105 return MC_SUCCESS;
00106 }
00107 MUTEX_DESTROY(acc->waiting_lock);
00108 free(acc->waiting_lock);
00109 COND_DESTROY(acc->waiting_cond);
00110 free(acc->waiting_cond);
00111 free(acc);
00112 acc = NULL;
00113 return MC_SUCCESS;
00114 }
00115
00116 #ifndef _WIN32
00117 void*
00118 acc_MessageHandlerThread(void* arg)
00119 #else
00120 DWORD WINAPI
00121 acc_MessageHandlerThread(LPVOID arg)
00122 #endif
00123 {
00124 mc_platform_p mc_platform = (mc_platform_p)arg;
00125 message_p message;
00126 agent_p agent;
00127 int mobile_agent_counter = 1;
00128 char* tmpstr;
00129 char* origname;
00130 int i;
00131
00132 while(1)
00133 {
00134 MUTEX_LOCK(mc_platform->message_queue->lock);
00135 MUTEX_LOCK(mc_platform->quit_lock);
00136 while(mc_platform->message_queue->size == 0 && !mc_platform->quit) {
00137 MUTEX_UNLOCK(mc_platform->quit_lock);
00138 COND_WAIT(
00139 mc_platform->message_queue->cond,
00140 mc_platform->message_queue->lock );
00141 MUTEX_LOCK(mc_platform->quit_lock);
00142 }
00143 if (mc_platform->message_queue->size == 0 && mc_platform->quit)
00144 {
00145 MUTEX_LOCK(&mc_platform->acc->msg_thread_lock);
00146 while(mc_platform->acc->num_msg_threads > 0) {
00147 COND_WAIT(
00148 &mc_platform->acc->msg_thread_cond,
00149 &mc_platform->acc->msg_thread_lock
00150 );
00151 }
00152 MUTEX_UNLOCK(&mc_platform->acc->msg_thread_lock);
00153 MUTEX_UNLOCK(mc_platform->quit_lock);
00154 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00155 THREAD_EXIT();
00156 }
00157
00158 MUTEX_UNLOCK(mc_platform->quit_lock);
00159 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00160 message = message_queue_Pop(mc_platform->message_queue);
00161 if (message == NULL) {
00162 printf("POP ERROR\n");
00163 continue;
00164 }
00165
00166 MUTEX_LOCK(mc_platform->MC_signal_lock);
00167 mc_platform->MC_signal = MC_RECV_MESSAGE;
00168 COND_BROADCAST(mc_platform->MC_signal_cond);
00169 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00170 MUTEX_LOCK(mc_platform->giant_lock);
00171 while(mc_platform->giant == 0) {
00172 COND_WAIT (
00173 mc_platform->giant_cond,
00174 mc_platform->giant_lock);
00175 }
00176 MUTEX_UNLOCK(mc_platform->giant_lock);
00177
00178
00179 if(message->to_address == NULL) {
00180
00181
00182 switch(message->message_type) {
00183 case MOBILE_AGENT:
00184 agent = agent_Initialize(
00185 mc_platform,
00186 message,
00187 mobile_agent_counter);
00188 if (agent != NULL) {
00189
00190 i = 1;
00191 if(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00192 origname = agent->name;
00193 while(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00194
00195
00196 tmpstr = (char*)malloc(sizeof(char) * strlen(origname) + 7);
00197 sprintf(tmpstr, "%s_%04d", origname, i);
00198 agent->name = tmpstr;
00199 i++;
00200 }
00201 fprintf(stderr, "Warning: Agent '%s' has been renamed to '%s'.\n",
00202 origname, agent->name);
00203 free(origname);
00204 }
00205 mobile_agent_counter++;
00206 agent_queue_Add(
00207 mc_platform->agent_queue,
00208 agent);
00209 } else {
00210 fprintf(stderr, "agent_Initialize() failed. %s:%d\n", __FILE__, __LINE__);
00211 }
00212 message_Destroy(message);
00213
00214 MUTEX_LOCK(mc_platform->MC_signal_lock);
00215 mc_platform->MC_signal = MC_RECV_AGENT;
00216 COND_BROADCAST(mc_platform->MC_signal_cond);
00217 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00218 MUTEX_LOCK(mc_platform->giant_lock);
00219 while(mc_platform->giant == 0) {
00220 COND_WAIT(mc_platform->giant_cond,
00221 mc_platform->giant_lock);
00222 }
00223 MUTEX_UNLOCK(mc_platform->giant_lock);
00224
00225 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00226 mc_platform->ams->run = 1;
00227 COND_BROADCAST(mc_platform->ams->runflag_cond);
00228 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00229 break;
00230 case FIPA_ACL:
00231
00232
00233 break;
00234 case RETURN_MSG:
00235
00236 agent = agent_Initialize(
00237 mc_platform,
00238 message,
00239 mobile_agent_counter);
00240 if (agent != NULL) {
00241 MUTEX_LOCK(agent->lock);
00242 agent->datastate->persistent = 1;
00243 agent->agent_status = MC_AGENT_NEUTRAL;
00244 MUTEX_UNLOCK(agent->lock);
00245 mobile_agent_counter++;
00246 agent_queue_Add(
00247 mc_platform->agent_queue,
00248 agent);
00249 }
00250 message_Destroy(message);
00251
00252 MUTEX_LOCK(mc_platform->MC_signal_lock);
00253 mc_platform->MC_signal = MC_RECV_RETURN;
00254 COND_BROADCAST(mc_platform->MC_signal_cond);
00255 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00256 MUTEX_LOCK(mc_platform->giant_lock);
00257 while(mc_platform->giant == 0) {
00258 COND_WAIT(
00259 mc_platform->giant_cond,
00260 mc_platform->giant_lock);
00261 }
00262 MUTEX_UNLOCK(mc_platform->giant_lock);
00263
00264 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00265 mc_platform->ams->run = 1;
00266 COND_BROADCAST(mc_platform->ams->runflag_cond);
00267 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00268 break;
00269 case RELAY:
00270 case REQUEST:
00271 case SUBSCRIBE:
00272 case CANCEL:
00273 case N_UNDRSTD:
00274 case QUER_IF:
00275 case QUER_REF:
00276 case AGENT_UPDATE:
00277 fprintf(stderr, "FIXME: Message type %d not processable.%s:%d\n",
00278 message->message_type, __FILE__, __LINE__ );
00279 message_Destroy(message);
00280 break;
00281 default:
00282 fprintf(stderr, "Unknown message type:%d %s:%d\n",
00283 message->message_type, __FILE__, __LINE__);
00284 message_Destroy(message);
00285 }
00286 } else {
00287 message_Send
00288 (
00289 mc_platform, message, mc_platform -> private_key
00290 );
00291 }
00292 }
00293 THREAD_EXIT();
00294 }
00295
00296
00297 #define CONN_THREADS 40
00298 #ifndef _WIN32
00299 void*
00300 acc_Thread(void* arg)
00301 #else
00302 DWORD WINAPI
00303 acc_Thread( LPVOID arg )
00304 #endif
00305 {
00306 connection_p connection;
00307 mc_platform_p mc_platform = (mc_platform_p)arg;
00308
00309 connection_thread_arg_t* connection_thread_arg;
00310
00311 acc_t* acc = mc_platform->acc;
00312
00313 #ifndef _WIN32
00314 pthread_attr_t attr;
00315 pthread_attr_init(&attr);
00316 #else
00317 int stack_size = 0;
00318 #endif
00319 THREAD_T conn_thread;
00320
00321
00322
00323 while(1) {
00324 connection = NULL;
00325 MUTEX_LOCK(mc_platform->connection_queue->lock);
00326 MUTEX_LOCK(mc_platform->quit_lock);
00327 while (
00328 (mc_platform->connection_queue->size == 0 ) && !mc_platform->quit) {
00329 MUTEX_UNLOCK(mc_platform->quit_lock);
00330 COND_WAIT(
00331 mc_platform->connection_queue->cond,
00332 mc_platform->connection_queue->lock
00333 );
00334 MUTEX_LOCK(mc_platform->quit_lock);
00335 }
00336 if
00337 (
00338 mc_platform->connection_queue->size == 0 &&
00339 mc_platform->quit
00340 )
00341 {
00342 MUTEX_LOCK(&mc_platform->acc->conn_thread_lock);
00343 while(mc_platform->acc->num_conn_threads > 0) {
00344 COND_WAIT(
00345 &mc_platform->acc->conn_thread_cond,
00346 &mc_platform->acc->conn_thread_lock
00347 );
00348 }
00349 MUTEX_UNLOCK(&mc_platform->acc->conn_thread_lock);
00350 MUTEX_UNLOCK(mc_platform->quit_lock);
00351 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00352 THREAD_EXIT();
00353 }
00354 MUTEX_UNLOCK(mc_platform->quit_lock);
00355 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00356
00357 MUTEX_LOCK(mc_platform->MC_signal_lock);
00358 mc_platform->MC_signal = MC_RECV_CONNECTION;
00359 COND_BROADCAST(mc_platform->MC_signal_cond);
00360 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00361
00362
00363 MUTEX_LOCK(mc_platform->giant_lock);
00364 while (mc_platform->giant == 0) {
00365 COND_WAIT(
00366 mc_platform->giant_cond,
00367 mc_platform->giant_lock
00368 );
00369 }
00370 MUTEX_UNLOCK(mc_platform->giant_lock);
00371
00372
00373 connection = connection_queue_Pop(mc_platform->connection_queue);
00374 connection_thread_arg = (connection_thread_arg_t*)malloc(sizeof(connection_thread_arg_t));
00375 connection_thread_arg->mc_platform = mc_platform;
00376 connection_thread_arg->connection = connection;
00377 MUTEX_LOCK(&acc->conn_thread_lock);
00378 while(acc->num_conn_threads > CONN_THREADS) {
00379 COND_WAIT(&acc->conn_thread_cond, &acc->conn_thread_lock);
00380 }
00381 acc->num_conn_threads++;
00382 MUTEX_UNLOCK(&acc->conn_thread_lock);
00383 THREAD_CREATE(&conn_thread, acc_connection_Thread, connection_thread_arg);
00384 THREAD_DETACH(conn_thread);
00385 }
00386 }
00387
00388
00389 #define CONNECT_THREAD_EXIT() \
00390 free(arg); \
00391 MUTEX_LOCK(&acc->conn_thread_lock); \
00392 acc->num_conn_threads--; \
00393 COND_SIGNAL(&acc->conn_thread_cond); \
00394 MUTEX_UNLOCK(&acc->conn_thread_lock); \
00395 THREAD_EXIT();
00396
00397 #ifndef _WIN32
00398 void*
00399 acc_connection_Thread(void* arg)
00400 #else
00401 DWORD WINAPI
00402 acc_connection_Thread( LPVOID arg )
00403 #endif
00404 {
00405 mtp_http_p mtp_http;
00406 acc_t* acc;
00407 mc_platform_t* mc_platform;
00408 connection_t* connection;
00409 message_p message;
00410 fipa_acl_envelope_p fipa_envelope;
00411 int err;
00412 int i, j;
00413 agent_t* agent;
00414 fipa_message_string_p fipa_message_string;
00415 fipa_acl_message_p fipa_message;
00416
00417 mc_platform = ((connection_thread_arg_t*)arg)->mc_platform;
00418 acc = ((connection_thread_arg_t*)arg)->mc_platform->acc;
00419 connection = ((connection_thread_arg_t*)arg)->connection;
00420 mtp_http = mtp_http_New();
00421 if ( mtp_http_InitializeFromConnection(mtp_http, connection, mc_platform->private_key ) )
00422 {
00423 fprintf(stderr, "mtp_http_InitializeFromConnection failed. %s:%d\n", __FILE__, __LINE__);
00424 connection_Destroy(connection);
00425 mtp_http_Destroy(mtp_http);
00426 CONNECT_THREAD_EXIT();
00427 }
00428
00429 switch(mtp_http->http_performative)
00430 {
00431 case HTTP_POST:
00432 case HTTP_PUT:
00433
00434
00435 if(
00436 !strcmp(mtp_http->target, "/ams") ||
00437 !strcmp( strrchr(mtp_http->target, (int)'/'), "/ams" )
00438 ) {
00439 message = message_New();
00440
00441 message->message_body = (char*)malloc
00442 (
00443 sizeof(char) *
00444 (strlen((char*)mtp_http->content->data)+1)
00445 );
00446 strcpy(message->message_body, (char*)mtp_http->content->data);
00447 message->xml_root = mxmlLoadString
00448 (
00449 NULL,
00450 message->message_body,
00451 MXML_NO_CALLBACK
00452 );
00453 if (message->xml_root == NULL) {
00454 fprintf(stderr, "xml loadstring error. %s:%d\n", __FILE__, __LINE__);
00455 }
00456 if(message_xml_parse(message)) {
00457 fprintf(stderr, "Error parsing message. %s:%d\n",
00458 __FILE__,__LINE__);
00459 message_Destroy(message);
00460 mtp_http_Destroy(mtp_http);
00461 CONNECT_THREAD_EXIT();
00462 }
00463 mtp_http_Destroy(mtp_http);
00464 break;
00465 } else if
00466 (
00467 !strcmp(mtp_http->target, "/acc") ||
00468 !strcmp( strrchr(mtp_http->target, (int)'/'), "/acc")
00469 ) {
00470
00471
00472 if (mtp_http->message_parts != 2) {
00473 fprintf(stderr, "Error parsing message. %s:%d\n",
00474 __FILE__,__LINE__);
00475 mtp_http_Destroy(mtp_http);
00476 CONNECT_THREAD_EXIT();
00477 }
00478
00479 fipa_envelope = fipa_acl_envelope_New();
00480 err = fipa_envelope_Parse(fipa_envelope, (char*)mtp_http->content[0].data);
00481 if (err) {
00482 fprintf(stderr, "Error parsing message. %s:%d\n",
00483 __FILE__, __LINE__);
00484 fipa_acl_envelope_Destroy(fipa_envelope);
00485 mtp_http_Destroy(mtp_http);
00486 CONNECT_THREAD_EXIT();
00487 }
00488
00489
00490 for(i = 0; i < fipa_envelope->num_params; i++) {
00491 char* portstr;
00492 for(j = 0; j < fipa_envelope->params[i]->to->num; j++) {
00493 agent = agent_queue_SearchName(
00494 mc_platform->agent_queue,
00495 fipa_envelope->params[i]->to->fipa_agent_identifiers[j]->name
00496 );
00497 if (agent != NULL) {
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 portstr = fipa_envelope->params[i]->to->fipa_agent_identifiers[j]->addresses->urls[0]->str;
00509 portstr = strstr(portstr, ":")+1;
00510 portstr = strstr(portstr, ":")+1;
00511
00512 if(agent->mc_platform->port != atoi(portstr)) continue;
00513
00514
00515 fipa_message_string = fipa_message_string_New();
00516 fipa_message_string->message = strdup((char*)mtp_http->content[1].data);
00517 fipa_message_string->parse = fipa_message_string->message;
00518 fipa_message = fipa_acl_message_New();
00519 err = fipa_acl_Parse(fipa_message, fipa_message_string);
00520 if (err) {
00521 fipa_message_string_Destroy(fipa_message_string);
00522 fipa_acl_message_Destroy(fipa_message);
00523 fipa_acl_envelope_Destroy(fipa_envelope);
00524 mtp_http_Destroy(mtp_http);
00525 CONNECT_THREAD_EXIT();
00526 }
00527 agent_mailbox_Post( agent->mailbox, fipa_message);
00528 fipa_message_string_Destroy(fipa_message_string);
00529 }
00530 }
00531 }
00532 fipa_acl_envelope_Destroy(fipa_envelope);
00533 mtp_http_Destroy(mtp_http);
00534 CONNECT_THREAD_EXIT();
00535 }
00536 else {
00537
00538 fprintf(stderr, "Unsupported. %s:%d\n", __FILE__, __LINE__);
00539 mtp_http_Destroy(mtp_http);
00540 }
00541 default:
00542 fprintf(stderr, "unsupported http performative. %s:%d\n",
00543 __FILE__, __LINE__);
00544 }
00545
00546
00547 connection_Destroy(connection);
00548 switch(message->message_type) {
00549 case RELAY:
00550 case REQUEST:
00551 case SUBSCRIBE:
00552 case CANCEL:
00553 case N_UNDRSTD:
00554 case MOBILE_AGENT:
00555 case QUER_IF:
00556 case QUER_REF:
00557 case AGENT_UPDATE:
00558 case RETURN_MSG:
00559 case FIPA_ACL:
00560 message_queue_Add(mc_platform->message_queue, message);
00561 break;
00562 default:
00563 fprintf(stderr, "Unknown message type:%d. Rejecting message.%s:%d\n",
00564 message->message_type,
00565 __FILE__, __LINE__ );
00566 free(message);
00567 break;
00568 }
00569 CONNECT_THREAD_EXIT();
00570 }
00571 #undef CONNECT_THREAD_EXIT
00572
00573
00574 void
00575 acc_Start(mc_platform_p mc_platform)
00576 {
00577 acc_p acc = mc_platform->acc;
00578 #ifndef _WIN32
00579 pthread_attr_t attr;
00580 pthread_attr_init(&attr);
00581 if(mc_platform->stack_size[MC_THREAD_ACC] != -1) {
00582 pthread_attr_setstacksize
00583 (
00584 &attr,
00585 mc_platform->stack_size[MC_THREAD_ACC]
00586 );
00587 }
00588 #else
00589 int stack_size;
00590 if (mc_platform->stack_size[MC_THREAD_ACC] < 1) {
00591
00592 stack_size = mc_platform->stack_size[MC_THREAD_ACC]+1;
00593 } else {
00594 stack_size = mc_platform->stack_size[MC_THREAD_ACC];
00595 }
00596 #endif
00597 THREAD_CREATE
00598 (
00599 &acc->thread,
00600 acc_Thread,
00601 mc_platform
00602 );
00603 THREAD_CREATE
00604 (
00605 &acc->message_handler_thread,
00606 acc_MessageHandlerThread,
00607 mc_platform
00608 );
00609 THREAD_CREATE
00610 (
00611 &acc->listen_thread,
00612 listen_Thread,
00613 mc_platform
00614 );
00615 THREAD_CREATE
00616 (
00617 &acc->udplisten_thread,
00618 udplisten_Thread,
00619 mc_platform
00620 );
00621 }
00622
00623 int
00624 auth_conn_rece_key(int sockfd, char *peer_name, int *nonce, unsigned char *aes_key, char *privkey, char* known_host_filename){
00625 int ret = -1;
00626
00627 char privatekey[1210];
00628 char peer_pubkey[300];
00629 char plaintext[135];
00630
00631
00632 memset(privatekey, '\0', 1210);
00633
00634 memset(plaintext, '\0', 135);
00635 memset(aes_key, '\0', 35);
00636
00637 strcpy(privatekey, privkey);
00638
00639
00640
00641 if (read_known_host_file(peer_pubkey, peer_name, known_host_filename) == -1 ){
00642 printf("Server: %s 's Public key not found in known host file\n",peer_name);
00643
00644 }else{
00645 if ( (ret=reply_migration_process(sockfd, nonce, peer_pubkey, privatekey, aes_key)) != 1){
00646 if (ret == -1)
00647 printf("Server: Connected peer is not authenticated \n");
00648 if (ret == -2)
00649 printf("Server: Unable to get authentication from other peer \n");
00650 }else{
00651 if(ret == 2)
00652 ret = 2;
00653 else
00654 ret = 1;
00655 }
00656 }
00657 return ret;
00658 }
00659
00660
00661 #ifndef _WIN32
00662 void*
00663 listen_Thread(void* arg)
00664 #else
00665 DWORD WINAPI
00666 listen_Thread( LPVOID arg )
00667 #endif
00668 {
00669 #ifndef _WIN32
00670 int connectionsockfd;
00671 int sockfd;
00672 struct sockaddr_in sktin;
00673 struct sockaddr_in peer_addr;
00674 #if HAVE_LIBBLUETOOTH
00675 #ifdef _WIN32
00676 SOCKADDR_BTH loc_addr = { 0 }, rem_addr = { 0 };
00677 #else
00678 struct sockaddr_rc loc_addr = { 0 };
00679 #endif
00680 #endif
00681 #else
00682 SOCKET connectionsockfd;
00683 SOCKET sockfd;
00684 struct sockaddr_in sktin;
00685 struct sockaddr_in peer_addr;
00686
00687 struct hostent *remoteHost;
00688 struct in_addr addr;
00689
00690 #endif
00691
00692 #ifdef NEW_SECURITY
00693 int ret;
00694 int nonce;
00695 unsigned char aes_key[36];
00696 #endif
00697
00698 char peer_name[45];
00699 connection_p connection;
00700 u_long connection_number;
00701 int connectionlen;
00702 #ifndef _WIN32
00703 int yes = 1;
00704 #else
00705 bool yes = true;
00706 #endif
00707 mc_platform_p mc_platform = (mc_platform_p)arg;
00708
00709
00710 connection_number = 0;
00711
00712
00713 if (mc_platform->bluetooth == 0) {
00714 connectionlen = sizeof(struct sockaddr_in);
00715 } else {
00716 #if HAVE_LIBBLUETOOTH
00717 #ifdef _WIN32
00718 connectionlen = sizeof(SOCKADDR_BTH);
00719 #else
00720 connectionlen = sizeof(struct sockaddr_rc);
00721 #endif
00722 #else
00723 fprintf(stderr, "ERROR: This copy of Mobile-C was not compiled with Bluetooth support, but\n"
00724 "bluetooth support was requested in the Mobile-C options. Please re-compile \n"
00725 "Mobile-C with Bluetooth support.\n");
00726 exit(-1);
00727 #endif
00728 }
00729
00730
00731 if(mc_platform->bluetooth) {
00732 #if HAVE_LIBBLUETOOTH
00733 #ifndef _WIN32
00734 sockfd = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
00735 #else
00736 sockfd = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
00737 #endif
00738 #endif
00739 } else {
00740 sockfd = socket(PF_INET, SOCK_STREAM, 0);
00741 }
00742 if (sockfd < 0) {
00743 SOCKET_ERROR();
00744 }
00745
00746 mc_platform->sockfd = sockfd;
00747 #ifndef _WIN32
00748 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
00749 #else
00750 setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int));
00751 #endif
00752
00753 if(mc_platform->bluetooth) {
00754 #if HAVE_LIBBLUETOOTH
00755 #ifndef _WIN32
00756 loc_addr.rc_family = AF_BLUETOOTH;
00757 loc_addr.rc_bdaddr = *BDADDR_ANY;
00758 loc_addr.rc_channel = (uint8_t) mc_platform->agency->portno;
00759 #else
00760 loc_addr.addressFamily= AF_BTH;
00761 loc_addr.btAddr = 0;
00762 loc_addr.port = mc_platform->agency->portno;
00763 #endif
00764 if(bind(sockfd, (struct sockaddr *)&loc_addr, sizeof(loc_addr))) {
00765 fprintf(stderr, "error binding to bluetooth socket. %s:%d\n",
00766 strerror(errno), errno);
00767 exit(1);
00768 }
00769 #endif
00770 } else {
00771 sktin.sin_family = AF_INET;
00772 sktin.sin_port = htons(mc_platform->port);
00773 sktin.sin_addr.s_addr = INADDR_ANY;
00774 memset(sktin.sin_zero, '\0', sizeof sktin.sin_zero);
00775 while(bind(sockfd, (struct sockaddr *)&sktin, sizeof(struct sockaddr))
00776 == -1) {
00777 fprintf(stderr, "bind() error. %s:%d\n",
00778 __FILE__, __LINE__ );
00779 #ifndef _WIN32
00780 sleep(1);
00781 #else
00782 Sleep(1000);
00783 #endif
00784 }
00785 }
00786 listen(sockfd, BACKLOG);
00787
00788
00789 while(1)
00790 {
00791
00792 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00793 mc_platform->acc->waiting = 1;
00794 COND_BROADCAST(mc_platform->acc->waiting_cond);
00795 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00796 #ifdef _WIN32
00797 if(mc_platform->bluetooth) {
00798 fprintf(stderr, "Warning: Windows Mobile-C Bluetooth Agencies only support sending agents.\nReceiving agents is unsupported. Disabling ACC listen thread...\n");
00799 while(1) {
00800 Sleep(10000);
00801 }
00802 }
00803 #endif
00804 if(mc_platform->bluetooth == 0) {
00805 #ifndef _WIN32
00806 if((connectionsockfd = accept(sockfd,
00807 (struct sockaddr *)&peer_addr,
00808 (socklen_t *)&connectionlen)) < 0)
00809 #else
00810 if((connectionsockfd = accept(sockfd,
00811 (struct sockaddr *)&peer_addr,
00812 (int*)&connectionlen)) == INVALID_SOCKET)
00813 #endif
00814 {
00815 fprintf(stderr, "ListenThread: accept error \n");
00816 #ifdef _WIN32
00817 printf("Error number: %d\n", WSAGetLastError() );
00818 #endif
00819 continue;
00820 }
00821 } else {
00822 #if HAVE_LIBBLUETOOTH
00823 #ifndef _WIN32
00824 if((connectionsockfd = accept(sockfd,
00825 (struct sockaddr *)&peer_addr,
00826 (socklen_t *)&connectionlen)) < 0)
00827 #else
00828 if((connectionsockfd = accept(sockfd,
00829 (struct sockaddr *)&rem_addr,
00830 (int*)&connectionlen)) == INVALID_SOCKET)
00831 #endif
00832 {
00833 fprintf(stderr, "ListenThread: accept error \n");
00834 #ifdef _WIN32
00835 printf("Error number: %d\n", WSAGetLastError() );
00836 #endif
00837 continue;
00838 }
00839 #endif
00840 }
00841 if(connectionsockfd > 0)
00842 {
00843
00844
00845 if(mc_platform->quit) {
00846 break;
00847 }
00848
00849
00850 #ifndef _WIN32
00851 getnameinfo((const struct sockaddr*)&peer_addr, sizeof(peer_addr),
00852 peer_name, sizeof(peer_name), NULL, 0, 0);
00853 #else
00854 addr.s_addr = inet_addr( inet_ntoa(peer_addr.sin_addr) );
00855 if (addr.s_addr == INADDR_NONE)
00856 printf("The IPv4 address entered must be a legal address\n");
00857 else
00858 remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
00859
00860 memset(peer_name, '\0', 45 );
00861 strcpy(peer_name, remoteHost->h_name);
00862
00863 #endif
00864
00865
00866 #ifdef NEW_SECURITY
00867
00868 ret = auth_conn_rece_key(connectionsockfd, peer_name, &nonce, aes_key, mc_platform->private_key, mc_platform->agency->known_host_filename);
00869 if( ret == 2 || ret == 1){
00870
00871
00872 #endif
00873
00874 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00875 mc_platform->acc->waiting = 0;
00876 COND_BROADCAST(mc_platform->acc->waiting_cond);
00877 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00878
00879
00880 connection = connection_New();
00881 connection->connect_id = rand();
00882 connection->remote_hostname = NULL;
00883 connection->addr = peer_addr;
00884 connection->serverfd = sockfd;
00885 connection->clientfd = connectionsockfd;
00886 #ifdef NEW_SECURITY
00887 connection->nonce = nonce;
00888 connection->AES_key = aes_key;
00889 #endif
00890
00891
00892 connection_queue_Add(mc_platform->connection_queue, connection);
00893 #ifdef NEW_SECURITY
00894 }else{
00895 printf("Unable to authenticate %s \n", peer_name);
00896 }
00897 #endif
00898 }
00899 }
00900
00901 #ifndef _WIN32
00902 if(close(sockfd) != 0)
00903 #else
00904 if(closesocket(sockfd) != 0)
00905 #endif
00906 {
00907 fprintf(stderr, "Socket close failed: %d\n", errno);
00908 }
00909
00910
00911 THREAD_EXIT();
00912 }
00913
00914 #define BUFLEN 512
00915 #define UDPPORT 8866
00916 #ifndef _WIN32
00917 void*
00918 udplisten_Thread(void* arg)
00919 #else
00920 DWORD WINAPI
00921 udplisten_Thread( LPVOID arg )
00922 #endif
00923 {
00924 mc_platform_p mc_platform = (mc_platform_p)arg;
00925 struct sockaddr_in si_me, si_remote;
00926 int s;
00927 #ifndef _WIN32
00928 unsigned int slen = sizeof(si_remote);
00929 #else
00930 int slen = sizeof(si_remote);
00931 #endif
00932 char buf[BUFLEN];
00933 char mc_req_string[] = "Mobile-C Agency Information Request";
00934
00935 if((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1 ) {
00936 perror("Socket error.");
00937 exit(1);
00938 }
00939
00940 memset((char*) &si_me, 0, sizeof(si_me));
00941 si_me.sin_family = AF_INET;
00942 si_me.sin_port = htons(UDPPORT);
00943 si_me.sin_addr.s_addr = htons(INADDR_ANY);
00944
00945 if(bind(s, (const struct sockaddr*)&si_me, sizeof(si_me)) == -1) {
00946
00947 return NULL;
00948 }
00949 while(1) {
00950 if (recvfrom(s, buf, BUFLEN, 0, (struct sockaddr*)&si_remote, &slen)==-1){
00951 perror("recvfrom");
00952 continue;
00953 }
00954
00955
00956
00957
00958
00959
00960 if(strncmp(buf, mc_req_string, strlen(mc_req_string)) == 0) {
00961 sprintf(buf, "Mobile-C Version %s\n%s:%d\n",
00962 PACKAGE_VERSION, mc_platform->hostname, mc_platform->port);
00963 if(sendto(s, buf, strlen(buf)+1, 0, (const struct sockaddr*)&si_remote, slen) == -1) {
00964 perror("sendto");
00965 }
00966 } else {
00967 sprintf(buf, "Message not understood.");
00968 if(sendto(s, buf, strlen(buf)+1, 0, (const struct sockaddr*)&si_remote, slen) == -1) {
00969 perror("sendto");
00970 }
00971 }
00972 }
00973 }
00974 #undef BUFLEN
00975 #undef UDPPORT