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 <winsock.h>
00048 #include <windows.h>
00049 #include <time.h>
00050 #include "winconfig.h"
00051 #endif
00052
00053 #include <stdlib.h>
00054 #include "include/acc.h"
00055 #include "include/connection.h"
00056 #include "include/data_structures.h"
00057 #include "include/macros.h"
00058 #include "include/mc_error.h"
00059 #include "include/mc_platform.h"
00060 #include "include/message.h"
00061 #include "include/mtp_http.h"
00062 #include "include/xml_parser.h"
00063 #include "include/fipa_acl_envelope.h"
00064
00065 #define BACKLOG 10
00066
00067 acc_p
00068 acc_Initialize(struct mc_platform_s* mc_platform)
00069 {
00070 acc_p acc;
00071 acc = (acc_p)malloc(sizeof(acc_t));
00072 acc->mc_platform = mc_platform;
00073
00074 acc->waiting = 0;
00075 acc->waiting_lock = (MUTEX_T*)malloc(sizeof(MUTEX_T));
00076 MUTEX_INIT(acc->waiting_lock);
00077 acc->waiting_cond = (COND_T*)malloc(sizeof(COND_T));
00078 COND_INIT(acc->waiting_cond);
00079
00080 return acc;
00081 }
00082
00083 int
00084 acc_Destroy(acc_p acc)
00085 {
00086 if(acc == NULL) {
00087 return MC_SUCCESS;
00088 }
00089 free(acc);
00090 acc = NULL;
00091 return MC_SUCCESS;
00092 }
00093
00094 #ifndef _WIN32
00095 void*
00096 acc_MessageHandlerThread(void* arg)
00097 #else
00098 DWORD WINAPI
00099 acc_MessageHandlerThread(LPVOID arg)
00100 #endif
00101 {
00102 mc_platform_p mc_platform = (mc_platform_p)arg;
00103 message_p message;
00104 agent_p agent;
00105 int mobile_agent_counter = 1;
00106 char* tmpstr;
00107 char* origname;
00108 int i;
00109
00110 while(1)
00111 {
00112 MUTEX_LOCK(mc_platform->message_queue->lock);
00113 MUTEX_LOCK(mc_platform->quit_lock);
00114 while(mc_platform->message_queue->size == 0 && !mc_platform->quit) {
00115 MUTEX_UNLOCK(mc_platform->quit_lock);
00116 COND_WAIT(
00117 mc_platform->message_queue->cond,
00118 mc_platform->message_queue->lock );
00119 MUTEX_LOCK(mc_platform->quit_lock);
00120 }
00121 if (mc_platform->message_queue->size == 0 && mc_platform->quit)
00122 {
00123 MUTEX_UNLOCK(mc_platform->quit_lock);
00124 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00125 THREAD_EXIT();
00126 }
00127
00128 MUTEX_UNLOCK(mc_platform->quit_lock);
00129 MUTEX_UNLOCK(mc_platform->message_queue->lock);
00130 message = message_queue_Pop(mc_platform->message_queue);
00131 if (message == NULL) {
00132 printf("POP ERROR\n");
00133 continue;
00134 }
00135
00136 MUTEX_LOCK(mc_platform->MC_signal_lock);
00137 mc_platform->MC_signal = MC_RECV_MESSAGE;
00138 COND_BROADCAST(mc_platform->MC_signal_cond);
00139 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00140 MUTEX_LOCK(mc_platform->giant_lock);
00141 while(mc_platform->giant == 0) {
00142 COND_WAIT (
00143 mc_platform->giant_cond,
00144 mc_platform->giant_lock);
00145 }
00146 MUTEX_UNLOCK(mc_platform->giant_lock);
00147
00148
00149 if(message->to_address == NULL) {
00150
00151
00152 switch(message->message_type) {
00153 case MOBILE_AGENT:
00154 agent = agent_Initialize(
00155 mc_platform,
00156 message,
00157 mobile_agent_counter);
00158 if (agent != NULL) {
00159
00160 i = 1;
00161 if(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00162 origname = agent->name;
00163 while(agent_queue_SearchName(mc_platform->agent_queue, agent->name)) {
00164
00165
00166 tmpstr = (char*)malloc(sizeof(char) * strlen(origname) + 7);
00167 sprintf(tmpstr, "%s_%04d", origname, i);
00168 agent->name = tmpstr;
00169 i++;
00170 }
00171 fprintf(stderr, "Warning: Agent '%s' has been renamed to '%s'.\n",
00172 origname, agent->name);
00173 free(origname);
00174 }
00175 mobile_agent_counter++;
00176 agent_queue_Add(
00177 mc_platform->agent_queue,
00178 agent);
00179 }
00180 message_Destroy(message);
00181
00182 MUTEX_LOCK(mc_platform->MC_signal_lock);
00183 mc_platform->MC_signal = MC_RECV_AGENT;
00184 COND_BROADCAST(mc_platform->MC_signal_cond);
00185 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00186 MUTEX_LOCK(mc_platform->giant_lock);
00187 while(mc_platform->giant == 0) {
00188 COND_WAIT(mc_platform->giant_cond,
00189 mc_platform->giant_lock);
00190 }
00191 MUTEX_UNLOCK(mc_platform->giant_lock);
00192
00193 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00194 mc_platform->ams->run = 1;
00195 COND_BROADCAST(mc_platform->ams->runflag_cond);
00196 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00197 break;
00198 case FIPA_ACL:
00199
00200
00201 break;
00202 case RETURN_MSG:
00203
00204 agent = agent_Initialize(
00205 mc_platform,
00206 message,
00207 mobile_agent_counter);
00208 if (agent != NULL) {
00209 MUTEX_LOCK(agent->lock);
00210 agent->datastate->persistent = 1;
00211 agent->agent_status = MC_AGENT_NEUTRAL;
00212 MUTEX_UNLOCK(agent->lock);
00213 mobile_agent_counter++;
00214 agent_queue_Add(
00215 mc_platform->agent_queue,
00216 agent);
00217 }
00218 message_Destroy(message);
00219
00220 MUTEX_LOCK(mc_platform->MC_signal_lock);
00221 mc_platform->MC_signal = MC_RECV_RETURN;
00222 COND_BROADCAST(mc_platform->MC_signal_cond);
00223 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00224 MUTEX_LOCK(mc_platform->giant_lock);
00225 while(mc_platform->giant == 0) {
00226 COND_WAIT(
00227 mc_platform->giant_cond,
00228 mc_platform->giant_lock);
00229 }
00230 MUTEX_UNLOCK(mc_platform->giant_lock);
00231
00232 MUTEX_LOCK(mc_platform->ams->runflag_lock);
00233 mc_platform->ams->run = 1;
00234 COND_BROADCAST(mc_platform->ams->runflag_cond);
00235 MUTEX_UNLOCK(mc_platform->ams->runflag_lock);
00236 break;
00237 case RELAY:
00238 case REQUEST:
00239 case SUBSCRIBE:
00240 case CANCEL:
00241 case N_UNDRSTD:
00242 case QUER_IF:
00243 case QUER_REF:
00244 case AGENT_UPDATE:
00245 fprintf(stderr, "FIXME: Message type %d not processable.%s:%d\n",
00246 message->message_type, __FILE__, __LINE__ );
00247 message_Destroy(message);
00248 break;
00249 default:
00250 fprintf(stderr, "Unknown message type:%d %s:%d\n",
00251 message->message_type, __FILE__, __LINE__);
00252 message_Destroy(message);
00253 }
00254 } else {
00255 message_Send
00256 (
00257 mc_platform, message, mc_platform -> private_key
00258 );
00259 message_Destroy
00260 (
00261 message
00262 );
00263 }
00264 }
00265 THREAD_EXIT();
00266 }
00267
00268 #ifndef _WIN32
00269 void*
00270 acc_Thread(void* arg)
00271 #else
00272 DWORD WINAPI
00273 acc_Thread( LPVOID arg )
00274 #endif
00275 {
00276 connection_p connection;
00277 message_p message;
00278 mtp_http_p mtp_http;
00279 mc_platform_p mc_platform = (mc_platform_p)arg;
00280 fipa_acl_envelope_p fipa_envelope;
00281 fipa_acl_message_p fipa_message;
00282 fipa_message_string_p fipa_message_string;
00283 int err;
00284 int i, j;
00285 agent_t* agent;
00286
00287
00288 while(1) {
00289 connection = NULL;
00290 message = NULL;
00291 mtp_http = NULL;
00292 MUTEX_LOCK(mc_platform->connection_queue->lock);
00293 MUTEX_LOCK(mc_platform->quit_lock);
00294 while (mc_platform->connection_queue->size == 0 && !mc_platform->quit) {
00295 MUTEX_UNLOCK(mc_platform->quit_lock);
00296 COND_WAIT(
00297 mc_platform->connection_queue->cond,
00298 mc_platform->connection_queue->lock
00299 );
00300 MUTEX_LOCK(mc_platform->quit_lock);
00301 }
00302 if
00303 (
00304 mc_platform->connection_queue->size == 0 &&
00305 mc_platform->quit
00306 )
00307 {
00308 MUTEX_UNLOCK(mc_platform->quit_lock);
00309 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00310 THREAD_EXIT();
00311 }
00312 MUTEX_UNLOCK(mc_platform->quit_lock);
00313 MUTEX_UNLOCK(mc_platform->connection_queue->lock);
00314
00315 MUTEX_LOCK(mc_platform->MC_signal_lock);
00316 mc_platform->MC_signal = MC_RECV_CONNECTION;
00317 COND_BROADCAST(mc_platform->MC_signal_cond);
00318 MUTEX_UNLOCK(mc_platform->MC_signal_lock);
00319
00320
00321 MUTEX_LOCK(mc_platform->giant_lock);
00322 while (mc_platform->giant == 0) {
00323 COND_WAIT(
00324 mc_platform->giant_cond,
00325 mc_platform->giant_lock
00326 );
00327 }
00328 MUTEX_UNLOCK(mc_platform->giant_lock);
00329
00330
00331 connection = connection_queue_Pop(mc_platform->connection_queue);
00332 mtp_http = mtp_http_New();
00333 if ( mtp_http_InitializeFromConnection(mtp_http, connection, mc_platform->private_key ) )
00334 {
00335 connection_Destroy(connection);
00336 mtp_http_Destroy(mtp_http);
00337 continue;
00338 }
00339
00340 switch(mtp_http->http_performative)
00341 {
00342 case HTTP_POST:
00343 case HTTP_PUT:
00344
00345
00346 if(
00347 !strcmp(mtp_http->target, "/ams") ||
00348 !strcmp( strrchr(mtp_http->target, (int)'/'), "/ams" )
00349 ) {
00350 message = message_New();
00351
00352 message->message_body = (char*)malloc
00353 (
00354 sizeof(char) *
00355 (strlen((char*)mtp_http->content->data)+1)
00356 );
00357 strcpy(message->message_body, (char*)mtp_http->content->data);
00358 message->xml_root = mxmlLoadString
00359 (
00360 NULL,
00361 message->message_body,
00362 MXML_NO_CALLBACK
00363 );
00364 if(message_xml_parse(message)) {
00365 fprintf(stderr, "Error parsing message. %s:%d\n",
00366 __FILE__,__LINE__);
00367 message_Destroy(message);
00368 mtp_http_Destroy(mtp_http);
00369 continue;
00370 }
00371 mtp_http_Destroy(mtp_http);
00372 break;
00373 } else if
00374 (
00375 !strcmp(mtp_http->target, "/acc") ||
00376 !strcmp( strrchr(mtp_http->target, (int)'/'), "/acc")
00377 ) {
00378
00379
00380 if (mtp_http->message_parts != 2) {
00381 fprintf(stderr, "Error parsing message. %s:%d\n",
00382 __FILE__,__LINE__);
00383 mtp_http_Destroy(mtp_http);
00384 continue;
00385 }
00386
00387 fipa_envelope = fipa_acl_envelope_New();
00388 err = fipa_envelope_Parse(fipa_envelope, (char*)mtp_http->content[0].data);
00389 if (err) {
00390 fprintf(stderr, "Error parsing message. %s:%d\n",
00391 __FILE__, __LINE__);
00392 fipa_acl_envelope_Destroy(fipa_envelope);
00393 mtp_http_Destroy(mtp_http);
00394 continue;
00395 }
00396
00397
00398 for(i = 0; i < fipa_envelope->num_params; i++) {
00399 for(j = 0; j < fipa_envelope->params[i]->to->num; j++) {
00400 agent = agent_queue_SearchName(
00401 mc_platform->agent_queue,
00402 fipa_envelope->params[i]->to->fipa_agent_identifiers[j]->name
00403 );
00404 if (agent != NULL) {
00405
00406 fipa_message_string = fipa_message_string_New();
00407 fipa_message_string->message = strdup((char*)mtp_http->content[1].data);
00408 fipa_message_string->parse = fipa_message_string->message;
00409 fipa_message = fipa_acl_message_New();
00410 err = fipa_acl_Parse(fipa_message, fipa_message_string);
00411 if (err) {
00412 fipa_message_string_Destroy(fipa_message_string);
00413 fipa_acl_message_Destroy(fipa_message);
00414 fipa_acl_envelope_Destroy(fipa_envelope);
00415 mtp_http_Destroy(mtp_http);
00416 continue;
00417 }
00418 agent_mailbox_Post( agent->mailbox, fipa_message);
00419 fipa_message_string_Destroy(fipa_message_string);
00420 }
00421 }
00422 }
00423 fipa_acl_envelope_Destroy(fipa_envelope);
00424 mtp_http_Destroy(mtp_http);
00425 continue;
00426 }
00427 else {
00428
00429 fprintf(stderr, "Unsupported. %s:%d\n", __FILE__, __LINE__);
00430 mtp_http_Destroy(mtp_http);
00431 }
00432 default:
00433 fprintf(stderr, "unsupported http performative. %s:%d\n",
00434 __FILE__, __LINE__);
00435 }
00436
00437
00438 connection_Destroy(connection);
00439 switch(message->message_type) {
00440 case RELAY:
00441 case REQUEST:
00442 case SUBSCRIBE:
00443 case CANCEL:
00444 case N_UNDRSTD:
00445 case MOBILE_AGENT:
00446 case QUER_IF:
00447 case QUER_REF:
00448 case AGENT_UPDATE:
00449 case RETURN_MSG:
00450 case FIPA_ACL:
00451 message_queue_Add(mc_platform->message_queue, message);
00452 break;
00453 default:
00454 fprintf(stderr, "Unknown message type:%d. Rejecting message.%s:%d\n",
00455 message->message_type,
00456 __FILE__, __LINE__ );
00457 free(message);
00458 break;
00459 }
00460 }
00461 }
00462
00463 void
00464 acc_Start(mc_platform_p mc_platform)
00465 {
00466 acc_p acc = mc_platform->acc;
00467 #ifndef _WIN32
00468 pthread_attr_t attr;
00469 pthread_attr_init(&attr);
00470 if(mc_platform->stack_size[MC_THREAD_ACC] != -1) {
00471 pthread_attr_setstacksize
00472 (
00473 &attr,
00474 mc_platform->stack_size[MC_THREAD_ACC]
00475 );
00476 }
00477 #else
00478 int stack_size;
00479 if (mc_platform->stack_size[MC_THREAD_ACC] < 1) {
00480
00481 stack_size = mc_platform->stack_size[MC_THREAD_ACC]+1;
00482 } else {
00483 stack_size = mc_platform->stack_size[MC_THREAD_ACC];
00484 }
00485 #endif
00486 THREAD_CREATE
00487 (
00488 &acc->thread,
00489 acc_Thread,
00490 mc_platform
00491 );
00492 THREAD_CREATE
00493 (
00494 &acc->message_handler_thread,
00495 acc_MessageHandlerThread,
00496 mc_platform
00497 );
00498 THREAD_CREATE
00499 (
00500 &acc->listen_thread,
00501 listen_Thread,
00502 mc_platform
00503 );
00504 }
00505
00506 int
00507 auth_conn_rece_key(int sockfd, char *peer_name, int *nonce, unsigned char *aes_key, char *privkey, char* known_host_filename){
00508 int ret = -1;
00509
00510 char privatekey[1210];
00511 char peer_pubkey[300];
00512 char plaintext[135];
00513
00514
00515 memset(privatekey, '\0', 1210);
00516
00517 memset(plaintext, '\0', 135);
00518 memset(aes_key, '\0', 35);
00519
00520 strcpy(privatekey, privkey);
00521
00522
00523
00524 if (read_known_host_file(peer_pubkey, peer_name, known_host_filename) == -1 ){
00525 printf("Server: %s 's Public key not found in known host file\n",peer_name);
00526
00527 }else{
00528 if ( (ret=reply_migration_process(sockfd, nonce, peer_pubkey, privatekey, aes_key)) != 1){
00529 if (ret == -1)
00530 printf("Server: Connected peer is not authenticated \n");
00531 if (ret == -2)
00532 printf("Server: Unable to get authentication from other peer \n");
00533 }else{
00534 if(ret == 2)
00535 ret = 2;
00536 else
00537 ret = 1;
00538 }
00539 }
00540 return ret;
00541 }
00542
00543
00544 #ifndef _WIN32
00545 void*
00546 listen_Thread(void* arg)
00547 #else
00548 DWORD WINAPI
00549 listen_Thread( LPVOID arg )
00550 #endif
00551 {
00552 #ifndef _WIN32
00553 int connectionsockfd;
00554 int sockfd;
00555 struct sockaddr_in sktin;
00556 struct sockaddr_in peer_addr;
00557 #else
00558 SOCKET connectionsockfd;
00559 SOCKET sockfd;
00560 struct sockaddr_in sktin;
00561 struct sockaddr_in peer_addr;
00562 struct sockaddr_in name_addr;
00563
00564 struct hostent *remoteHost;
00565 struct in_addr addr;
00566
00567 #endif
00568
00569 unsigned char aes_key[35];
00570 int nonce, ret;
00571 char peer_name[45];
00572 connection_p connection;
00573 u_long connection_number;
00574 int connectionlen;
00575 mc_platform_p mc_platform = (mc_platform_p)arg;
00576
00577
00578 connection_number = 0;
00579
00580 connectionlen = sizeof(struct sockaddr_in);
00581
00582
00583 sockfd = socket(PF_INET, SOCK_STREAM, 0);
00584 mc_platform->sockfd = sockfd;
00585 sktin.sin_family = AF_INET;
00586 sktin.sin_port = htons(mc_platform->port);
00587 sktin.sin_addr.s_addr = INADDR_ANY;
00588 memset(sktin.sin_zero, '\0', sizeof sktin.sin_zero);
00589 if (bind(sockfd, (struct sockaddr *)&sktin, sizeof(struct sockaddr))
00590 == -1) {
00591 fprintf(stderr, "bind() error. %s:%d\n",
00592 __FILE__, __LINE__ );
00593 exit(1);
00594 }
00595 listen(sockfd, BACKLOG);
00596
00597
00598 while(1)
00599 {
00600
00601 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00602 mc_platform->acc->waiting = 1;
00603 COND_BROADCAST(mc_platform->acc->waiting_cond);
00604 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00605 #ifndef _WIN32
00606 if((connectionsockfd = accept(sockfd,
00607 (struct sockaddr *)&peer_addr,
00608 (socklen_t *)&connectionlen)) < 0)
00609 #else
00610 if((connectionsockfd = accept(sockfd,
00611 (struct sockaddr *)&peer_addr,
00612 (int*)&connectionlen)) == INVALID_SOCKET)
00613 #endif
00614 {
00615 fprintf(stderr, "ListenThread: accept error \n");
00616 #ifdef _WIN32
00617 printf("Error number: %d\n", WSAGetLastError() );
00618 #endif
00619 continue;
00620 }
00621 else
00622 {
00623
00624 #ifndef _WIN32
00625 getnameinfo(&peer_addr, sizeof(peer_addr),
00626 peer_name, sizeof(peer_name), NULL, 0, 0);
00627 #else
00628 addr.s_addr = inet_addr( inet_ntoa(peer_addr.sin_addr) );
00629 if (addr.s_addr == INADDR_NONE)
00630 printf("The IPv4 address entered must be a legal address\n");
00631 else
00632 remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
00633
00634 memset(peer_name, '\0', 45 );
00635 strcpy(peer_name, remoteHost->h_name);
00636
00637 #endif
00638
00639
00640 #ifdef NEW_SECURITY
00641
00642 ret = auth_conn_rece_key(connectionsockfd, peer_name, &nonce, aes_key, mc_platform->private_key, mc_platform->agency->known_host_filename);
00643 if( ret == 2 || ret == 1){
00644
00645
00646 #endif
00647
00648 MUTEX_LOCK(mc_platform->acc->waiting_lock);
00649 mc_platform->acc->waiting = 0;
00650 COND_BROADCAST(mc_platform->acc->waiting_cond);
00651 MUTEX_UNLOCK(mc_platform->acc->waiting_lock);
00652
00653
00654 connection = (connection_p)malloc(sizeof(connection_t));
00655 CHECK_NULL(connection, exit(0););
00656 connection->connect_id = rand();
00657 connection->remote_hostname = NULL;
00658 connection->addr = peer_addr;
00659 connection->serverfd = sockfd;
00660 connection->clientfd = connectionsockfd;
00661 #ifdef NEW_SECURITY
00662 connection->nonce = nonce;
00663 connection->AES_key = aes_key;
00664 #endif
00665
00666
00667 connection_queue_Add(mc_platform->connection_queue, connection);
00668 #ifdef NEW_SECURITY
00669 }else{
00670 printf("Unable to authenticate %s \n", peer_name);
00671 }
00672 #endif
00673 }
00674 }
00675
00676
00677 THREAD_EXIT();
00678 }