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