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