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