1 /******************************************************************************* 2 * Copyright (C) 2004-2008 Intel Corp. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * - Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * - Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * - Neither the name of Intel Corp. nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 *******************************************************************************/ 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 #include <cerrno> 35 #include "types.h" 36 #include "LMEConnection.h" 37 #include "LMS_if.h" 38 #include "Lock.h" 39 #include "glue.h" 40 41 #if defined(__sun) || defined(_LINUX) 42 #include <netinet/in.h> 43 #define _strnicmp strncasecmp 44 #endif // __sun || _LINUX 45 46 #define HECI_IO_TIMEOUT 5000 47 48 extern glue plugin; 49 50 const GUID LMEConnection::_guid = {0x6733a4db, 0x0476, 0x4e7b, {0xb3, 0xaf, 0xbc, 0xfc, 0x29, 0xbe, 0xe7, 0xa7}}; 51 52 const UINT32 LMEConnection::RX_WINDOW_SIZE = 1024; 53 54 LMEConnection::LMEConnection(bool verbose) : 55 _reqID(0), 56 _txBuffer(NULL), 57 _rxThread(NULL), 58 _cb(NULL), 59 _cbParam(NULL), 60 _initState(INIT_STATE_DISCONNECTED), 61 _heci(_guid, verbose), 62 _heciCompat(_guidCompat, verbose), 63 _pHeci(NULL) 64 { 65 } 66 67 LMEConnection::~LMEConnection() 68 { 69 } 70 71 bool LMEConnection::IsInitialized() 72 { 73 Lock il(_initLock); 74 return ((_initState == INIT_STATE_CONNECTED) ? true : false); 75 } 76 77 bool LMEConnection::Init(HECICallback cb, void *param) 78 { 79 Lock il(_initLock); 80 81 if (_initState == INIT_STATE_CONNECTING) { 82 return false; 83 } 84 _initState = INIT_STATE_CONNECTING; 85 86 _cb = cb; 87 _cbParam = param; 88 89 if (_heci.Init(LMS_PROCOL_VERSION)) { 90 protocolVer = _heci.GetProtocolVersion(); 91 _pHeci = &_heci; 92 } else if (_heciCompat.Init()) { 93 protocolVer = _heciCompat.GetProtocolVersion(); 94 if (protocolVer > LMS_PROCOL_VERSION_COMPAT) { 95 _heciCompat.Deinit(); 96 _initState = INIT_STATE_DISCONNECTED; 97 return false; 98 } 99 _pHeci = &_heciCompat; 100 } else { 101 _initState = INIT_STATE_DISCONNECTED; 102 return false; 103 } 104 105 _initState = INIT_STATE_CONNECTED; 106 107 plugin.version(protocolVer); 108 109 // launch RX thread 110 _txBuffer = new unsigned char[_pHeci->GetBufferSize()]; 111 _rxThread = new Thread(_rxThreadFunc, this); 112 _rxThread->start(); 113 114 _threadStartedEvent.wait(); 115 return true; 116 } 117 118 void LMEConnection::Deinit() 119 { 120 Lock il(_initLock); 121 122 _initState = INIT_STATE_DISCONNECTED; 123 124 if (_pHeci != NULL) { 125 _pHeci->Deinit(); 126 _pHeci = NULL; 127 } 128 129 if (_rxThread != NULL) { 130 delete _rxThread; 131 _rxThread = NULL; 132 } 133 134 if (_txBuffer != NULL) { 135 delete[] _txBuffer; 136 _txBuffer = NULL; 137 } 138 } 139 140 bool LMEConnection::Disconnect(APF_DISCONNECT_REASON_CODE reasonCode) 141 { 142 if (!IsInitialized()) { 143 PRINT("State: not connected to HECI.\n"); 144 return false; 145 } 146 147 unsigned char buf[sizeof(APF_DISCONNECT_MESSAGE)]; 148 149 APF_DISCONNECT_MESSAGE *disconnectMessage = (APF_DISCONNECT_MESSAGE *)buf; 150 151 memset(disconnectMessage, 0, sizeof(buf)); 152 disconnectMessage->MessageType = APF_DISCONNECT; 153 disconnectMessage->ReasonCode = htonl(reasonCode); 154 155 PRINT("Sending disconnect to LME.\n"); 156 int res = _sendMessage(buf, sizeof(buf)); 157 158 return (res == sizeof(buf)); 159 } 160 161 bool LMEConnection::ServiceAccept(std::string serviceName) 162 { 163 if (!IsInitialized()) { 164 PRINT("State: not connected to HECI.\n"); 165 return false; 166 } 167 168 //APF_SERVICE_ACCEPT_MESSAGE 169 //memcpy(pCurrent, "127.0.0.1", APF_STR_SIZE_OF("127.0.0.1")); 170 //pCurrent += APF_STR_SIZE_OF("127.0.0.1"); 171 unsigned char *buf = new unsigned char[sizeof(APF_SERVICE_ACCEPT_MESSAGE) + serviceName.length()]; 172 if (buf == NULL) { 173 PRINT("Failed to allocate memory for ServiceAccept.\n"); 174 return false; 175 } 176 177 unsigned char *pCurrent = buf; 178 *pCurrent = APF_SERVICE_ACCEPT; 179 ++pCurrent; 180 *((UINT32 *)pCurrent) = htonl(serviceName.size()); 181 pCurrent += 4; 182 183 memcpy(pCurrent, serviceName.c_str(), serviceName.size()); 184 pCurrent += serviceName.size(); 185 186 PRINT("Sending service accept to LME: %s\n", serviceName.c_str()); 187 int len = pCurrent - buf; 188 int res = _sendMessage(buf, len); 189 190 delete [] buf; 191 192 return (res == len); 193 } 194 195 bool LMEConnection::UserAuthSuccess() 196 { 197 if (!IsInitialized()) { 198 PRINT("State: not connected to HECI.\n"); 199 return false; 200 } 201 202 unsigned char buf = APF_USERAUTH_SUCCESS; 203 204 PRINT("Sending user authentication success to LME.\n"); 205 int res = _sendMessage(&buf, sizeof(buf)); 206 207 return (res == sizeof(buf)); 208 } 209 210 bool LMEConnection::ProtocolVersion(const LMEProtocolVersionMessage versionMessage) 211 { 212 if (!IsInitialized()) { 213 PRINT("State: not connected to HECI.\n"); 214 return false; 215 } 216 217 APF_PROTOCOL_VERSION_MESSAGE protVersion; 218 memset(&protVersion, 0, sizeof(protVersion)); 219 220 protVersion.MessageType = APF_PROTOCOLVERSION; 221 protVersion.MajorVersion = htonl(versionMessage.MajorVersion); 222 protVersion.MinorVersion = htonl(versionMessage.MinorVersion); 223 protVersion.TriggerReason = htonl(versionMessage.TriggerReason); 224 225 PRINT("Sending protocol version to LME: %d.%d\n", versionMessage.MajorVersion, versionMessage.MinorVersion); 226 int res = _sendMessage((unsigned char *)&protVersion, sizeof(protVersion)); 227 228 return (res == sizeof(protVersion)); 229 } 230 231 bool LMEConnection::TcpForwardReplySuccess(UINT32 port) 232 { 233 if (!IsInitialized()) { 234 PRINT("State: not connected to HECI.\n"); 235 return false; 236 } 237 238 APF_TCP_FORWARD_REPLY_MESSAGE message; 239 240 message.MessageType = APF_REQUEST_SUCCESS; 241 message.PortBound = htonl(port); 242 243 PRINT("Sending TCP forward replay success to LME: Port %d.\n", port); 244 int res = _sendMessage((unsigned char *)&message, sizeof(message)); 245 246 return (res == sizeof(message)); 247 } 248 249 bool LMEConnection::TcpForwardReplyFailure() 250 { 251 if (!IsInitialized()) { 252 PRINT("State: not connected to HECI.\n"); 253 return false; 254 } 255 256 unsigned char buf = APF_REQUEST_FAILURE; 257 258 PRINT("Sending TCP forward replay failure to LME.\n"); 259 int res = _sendMessage(&buf, sizeof(buf)); 260 261 return (res == sizeof(buf)); 262 } 263 264 bool LMEConnection::TcpForwardCancelReplySuccess() 265 { 266 if (!IsInitialized()) { 267 PRINT("State: not connected to HECI.\n"); 268 return false; 269 } 270 271 unsigned char buf = APF_REQUEST_SUCCESS; 272 273 PRINT("Sending TCP forward cancel replay success to LME.\n"); 274 int res = _sendMessage(&buf, sizeof(buf)); 275 276 return (res == sizeof(buf)); 277 } 278 279 bool LMEConnection::TcpForwardCancelReplyFailure() 280 { 281 if (!IsInitialized()) { 282 PRINT("State: not connected to HECI.\n"); 283 return false; 284 } 285 286 unsigned char buf = APF_REQUEST_FAILURE; 287 288 PRINT("Sending TCP forward cancel replay failure to LME.\n"); 289 int res = _sendMessage(&buf, sizeof(buf)); 290 291 return (res == sizeof(buf)); 292 } 293 294 bool LMEConnection::ChannelOpenForwardedRequest(UINT32 senderChannel, 295 UINT32 connectedPort, 296 std::string originatorIP, 297 UINT32 originatorPort) 298 { 299 if (!IsInitialized()) { 300 PRINT("State: not connected to HECI.\n"); 301 return false; 302 } 303 304 unsigned char buf[5 + APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED) + 16 + 305 APF_STR_SIZE_OF("127.0.0.1") + 8 + 16 + 4]; 306 unsigned char *pCurrent = buf; 307 308 if (originatorIP.size() > 16) { 309 return false; 310 } 311 312 *pCurrent = APF_CHANNEL_OPEN; 313 ++pCurrent; 314 315 *((UINT32 *)pCurrent) = htonl(APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED)); 316 pCurrent += sizeof(UINT32); 317 318 memcpy(pCurrent, APF_OPEN_CHANNEL_REQUEST_FORWARDED, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED)); 319 pCurrent += APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED); 320 321 *((UINT32 *)pCurrent) = htonl(senderChannel); 322 pCurrent += sizeof(UINT32); 323 324 *((UINT32 *)pCurrent) = htonl(RX_WINDOW_SIZE); 325 pCurrent += sizeof(UINT32); 326 327 *((UINT32 *)pCurrent) = 0xFFFFFFFF; 328 pCurrent += sizeof(UINT32); 329 330 *((UINT32 *)pCurrent) = htonl(APF_STR_SIZE_OF("127.0.0.1")); 331 pCurrent += sizeof(UINT32); 332 333 memcpy(pCurrent, "127.0.0.1", APF_STR_SIZE_OF("127.0.0.1")); 334 pCurrent += APF_STR_SIZE_OF("127.0.0.1"); 335 336 *((UINT32 *)pCurrent) = htonl(connectedPort); 337 pCurrent += sizeof(UINT32); 338 339 *((UINT32 *)pCurrent) = htonl((UINT32)originatorIP.size()); 340 pCurrent += sizeof(UINT32); 341 342 memcpy(pCurrent, originatorIP.c_str(), originatorIP.size()); 343 pCurrent += originatorIP.size(); 344 345 *((UINT32 *)pCurrent) = htonl(originatorPort); 346 pCurrent += sizeof(UINT32); 347 348 PRINT("Sending channel open request to LME. Address: %s, requested port: %d.\n", 349 originatorIP.c_str(), connectedPort); 350 int res = _sendMessage(buf, (int)(pCurrent - buf)); 351 352 return (res == pCurrent - buf); 353 } 354 355 bool LMEConnection::ChannelOpenReplaySuccess(UINT32 recipientChannel, 356 UINT32 senderChannel) 357 { 358 if (!IsInitialized()) { 359 PRINT("State: not connected to HECI.\n"); 360 return false; 361 } 362 363 APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE message; 364 365 message.MessageType = APF_CHANNEL_OPEN_CONFIRMATION; 366 message.RecipientChannel = htonl(recipientChannel); 367 message.SenderChannel = htonl(senderChannel); 368 message.InitialWindowSize = htonl(RX_WINDOW_SIZE); 369 message.Reserved = 0xFFFFFFFF; 370 371 PRINT("Sending channel open replay success to LME. Recipient: %d.\n", recipientChannel); 372 int res = _sendMessage((unsigned char *)&message, sizeof(message)); 373 374 return (res == sizeof(message)); 375 } 376 377 bool LMEConnection::ChannelOpenReplayFailure(UINT32 recipientChannel, 378 UINT32 reason) 379 { 380 if (!IsInitialized()) { 381 PRINT("State: not connected to HECI.\n"); 382 return false; 383 } 384 385 APF_CHANNEL_OPEN_FAILURE_MESSAGE message; 386 387 message.MessageType = APF_CHANNEL_OPEN_FAILURE; 388 message.RecipientChannel = htonl(recipientChannel); 389 message.ReasonCode = htonl(reason); 390 message.Reserved = 0x00000000; 391 message.Reserved2 = 0x00000000; 392 393 PRINT("Sending channel open replay failure to LME. Recipient: %d, Reason: %d.\n", recipientChannel, reason); 394 int res = _sendMessage((unsigned char *)&message, sizeof(message)); 395 396 return (res == sizeof(message)); 397 } 398 399 bool LMEConnection::ChannelClose(UINT32 recipientChannel) 400 { 401 if (!IsInitialized()) { 402 PRINT("State: not connected to HECI.\n"); 403 return false; 404 } 405 406 APF_CHANNEL_CLOSE_MESSAGE message; 407 408 message.MessageType = APF_CHANNEL_CLOSE; 409 message.RecipientChannel = htonl(recipientChannel); 410 411 PRINT("Sending channel close to LME. Recipient: %d.\n", recipientChannel); 412 int res = _sendMessage((unsigned char *)&message, sizeof(message)); 413 414 return (res == sizeof(message)); 415 } 416 417 int LMEConnection::ChannelData(UINT32 recipientChannel, 418 UINT32 len, unsigned char *buffer) 419 { 420 if (!IsInitialized()) { 421 PRINT("State: not connected to HECI.\n"); 422 return false; 423 } 424 425 APF_CHANNEL_DATA_MESSAGE *message; 426 427 if (len > _heci.GetBufferSize() - sizeof(APF_CHANNEL_DATA_MESSAGE)) { 428 return -1; 429 } 430 431 message = (APF_CHANNEL_DATA_MESSAGE *)_txBuffer; 432 message->MessageType = APF_CHANNEL_DATA; 433 message->RecipientChannel = htonl(recipientChannel); 434 message->DataLength = htonl(len); 435 memcpy(message->Data, buffer, len); 436 437 PRINT("Sending %d bytes to recipient channel %d.\n", len, recipientChannel); 438 return _sendMessage((unsigned char *)message, sizeof(APF_CHANNEL_DATA_MESSAGE) + len); 439 } 440 441 bool LMEConnection::ChannelWindowAdjust(UINT32 recipientChannel, UINT32 len) 442 { 443 if (!IsInitialized()) { 444 PRINT("State: not connected to HECI.\n"); 445 return false; 446 } 447 448 APF_WINDOW_ADJUST_MESSAGE message; 449 450 message.MessageType = APF_CHANNEL_WINDOW_ADJUST; 451 message.RecipientChannel = htonl(recipientChannel); 452 message.BytesToAdd = htonl(len); 453 454 PRINT("Sending Window Adjust with %d bytes to recipient channel %d.\n", len, recipientChannel); 455 int res = _sendMessage((unsigned char *)&message, sizeof(message)); 456 457 return (res == sizeof(message)); 458 } 459 460 int LMEConnection::_receiveMessage(unsigned char *buffer, int len) 461 { 462 int result; 463 464 if (!IsInitialized()) { 465 return -1; 466 } 467 468 result = _pHeci->ReceiveMessage(buffer, len, WAIT_INFINITE); 469 470 if (result < 0 && errno == ENOENT) { 471 Lock il(_initLock); 472 _initState = INIT_STATE_DISCONNECTED; 473 } 474 475 return result; 476 } 477 478 int LMEConnection::_sendMessage(unsigned char *buffer, int len) 479 { 480 int result; 481 482 if (!IsInitialized()) { 483 return -1; 484 } 485 486 _sendMessageLock.acquire(); 487 result = _pHeci->SendMessage(buffer, len, HECI_IO_TIMEOUT); 488 _sendMessageLock.release(); 489 490 if (result < 0 && errno == ENOENT) { 491 Lock il(_initLock); 492 _initState = INIT_STATE_DISCONNECTED; 493 } 494 495 return result; 496 } 497 498 void LMEConnection::_rxThreadFunc(void *param) 499 { 500 LMEConnection *connection = (LMEConnection *)param; 501 502 try { 503 if (LMS_PROCOL_VERSION == connection->protocolVer) { 504 connection->_doRX(); 505 } else if (LMS_PROCOL_VERSION_COMPAT == connection->protocolVer) { 506 connection->_doRXCompat(); 507 } 508 } 509 catch (...) { 510 PRINT("LMEConnection do RX exception\n"); 511 } 512 pthread_exit(NULL); 513 } 514 515 bool LMEConnection::_checkMinMsgSize(unsigned char *buf, unsigned int bytesRead) 516 { 517 switch (buf[0]) { 518 case APF_DISCONNECT: 519 if (bytesRead < sizeof(APF_DISCONNECT_MESSAGE)) { 520 return false; 521 } 522 break; 523 case APF_SERVICE_REQUEST: 524 if (bytesRead < sizeof(APF_SERVICE_REQUEST)) { 525 return false; 526 } 527 if (bytesRead < (sizeof(APF_SERVICE_REQUEST) + 528 ntohl(((APF_SERVICE_REQUEST_MESSAGE *)buf)->ServiceNameLength))) { 529 return false; 530 } 531 break; 532 case APF_USERAUTH_REQUEST: 533 if (bytesRead < (3 * sizeof(UINT32))) { 534 return false; 535 } 536 break; 537 case APF_GLOBAL_REQUEST: 538 if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8))) { 539 return false; 540 } 541 if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8) + 542 ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { 543 return false; 544 } 545 break; 546 case APF_CHANNEL_OPEN: 547 if (bytesRead < sizeof(APF_GENERIC_HEADER)) { 548 return false; 549 } 550 if (bytesRead < (sizeof(APF_GENERIC_HEADER) + 551 ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { 552 return false; 553 } 554 break; 555 case APF_CHANNEL_OPEN_CONFIRMATION: 556 if (bytesRead < sizeof(APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE)) { 557 return false; 558 } 559 break; 560 case APF_CHANNEL_OPEN_FAILURE: 561 if (bytesRead < sizeof(APF_CHANNEL_OPEN_FAILURE_MESSAGE)) { 562 return false; 563 } 564 break; 565 case APF_CHANNEL_CLOSE: 566 if (bytesRead < sizeof(APF_CHANNEL_CLOSE_MESSAGE)) { 567 return false; 568 } 569 break; 570 case APF_CHANNEL_DATA: 571 if (bytesRead < sizeof(APF_CHANNEL_DATA_MESSAGE)) { 572 return false; 573 } 574 if (bytesRead < (sizeof(APF_CHANNEL_DATA_MESSAGE) + 575 ntohl(((APF_CHANNEL_DATA_MESSAGE *)buf)->DataLength))) { 576 return false; 577 } 578 break; 579 case APF_CHANNEL_WINDOW_ADJUST: 580 if (bytesRead < sizeof(APF_WINDOW_ADJUST_MESSAGE)) { 581 return false; 582 } 583 break; 584 case APF_PROTOCOLVERSION: 585 if (bytesRead < sizeof(APF_PROTOCOL_VERSION_MESSAGE)) { 586 return false; 587 } 588 break; 589 default: 590 return false; 591 } 592 return true; 593 } 594 595 void LMEConnection::_doRX() 596 { 597 unsigned int bytesRead; 598 int status = 1; 599 600 _threadStartedEvent.set(); 601 602 unsigned char *rxBuffer = new unsigned char[_heci.GetBufferSize()]; 603 604 while (true) { 605 bytesRead = (unsigned int)_receiveMessage(rxBuffer, _heci.GetBufferSize()); 606 607 if ((int)bytesRead < 0) { 608 PRINT("Error receiving data from HECI\n"); 609 Deinit(); 610 break; 611 } 612 613 if (bytesRead == 0) { 614 // ERROR 615 continue; 616 } 617 618 PRINT("Received from LME %d bytes (msg type %02d)\n", bytesRead, rxBuffer[0]); 619 620 if (!_checkMinMsgSize(rxBuffer, bytesRead)) { 621 PRINT("Error receiving data from HECI\n"); 622 Deinit(); 623 break; 624 } 625 626 if (plugin.preprocess(rxBuffer, bytesRead) == LMS_DROPPED) { 627 continue; 628 } 629 630 switch (rxBuffer[0]) { 631 case APF_DISCONNECT: 632 { 633 LMEDisconnectMessage disconnectMessage( 634 (APF_DISCONNECT_REASON_CODE)ntohl( 635 ((APF_DISCONNECT_MESSAGE *)rxBuffer)->ReasonCode)); 636 637 _cb(_cbParam, &disconnectMessage, sizeof(disconnectMessage), &status); 638 } 639 break; 640 641 case APF_SERVICE_REQUEST: 642 { 643 APF_SERVICE_REQUEST_MESSAGE *pMessage = 644 (APF_SERVICE_REQUEST_MESSAGE *)rxBuffer; 645 LMEServiceRequestMessage serviceRequestMessage; 646 647 serviceRequestMessage.ServiceName.append( 648 (char *)(pMessage->ServiceName), 649 ntohl(pMessage->ServiceNameLength)); 650 651 _cb(_cbParam, &serviceRequestMessage, sizeof(serviceRequestMessage), &status); 652 } 653 break; 654 655 case APF_USERAUTH_REQUEST: 656 _apfUserAuthRequest(rxBuffer, bytesRead, &status); 657 break; 658 659 case APF_GLOBAL_REQUEST: 660 _apfGlobalRequest(rxBuffer, bytesRead, &status); 661 break; 662 663 case APF_CHANNEL_OPEN: 664 _apfChannelOpen(rxBuffer, bytesRead, &status); 665 break; 666 667 case APF_CHANNEL_OPEN_CONFIRMATION: 668 { 669 APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *pMessage = 670 (APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *)rxBuffer; 671 LMEChannelOpenReplaySuccessMessage channelOpenReply; 672 673 channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel); 674 channelOpenReply.SenderChannel = ntohl(pMessage->SenderChannel); 675 channelOpenReply.InitialWindow = ntohl(pMessage->InitialWindowSize); 676 _cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status); 677 } 678 break; 679 680 case APF_CHANNEL_OPEN_FAILURE: 681 { 682 APF_CHANNEL_OPEN_FAILURE_MESSAGE *pMessage = 683 (APF_CHANNEL_OPEN_FAILURE_MESSAGE *)rxBuffer; 684 LMEChannelOpenReplayFailureMessage channelOpenReply; 685 686 channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel); 687 channelOpenReply.ReasonCode = 688 (OPEN_FAILURE_REASON)(ntohl(pMessage->ReasonCode)); 689 _cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status); 690 } 691 break; 692 693 case APF_CHANNEL_CLOSE: 694 { 695 APF_CHANNEL_CLOSE_MESSAGE *pMessage = 696 (APF_CHANNEL_CLOSE_MESSAGE *)rxBuffer; 697 LMEChannelCloseMessage channelClose; 698 699 channelClose.RecipientChannel = ntohl(pMessage->RecipientChannel); 700 _cb(_cbParam, &channelClose, sizeof(channelClose), &status); 701 } 702 break; 703 704 case APF_CHANNEL_DATA: 705 { 706 APF_CHANNEL_DATA_MESSAGE *pMessage = 707 (APF_CHANNEL_DATA_MESSAGE *)rxBuffer; 708 LMEChannelDataMessage channelData(ntohl(pMessage->RecipientChannel), 709 ntohl(pMessage->DataLength), 710 pMessage->Data); 711 _cb(_cbParam, &channelData, sizeof(channelData), &status); 712 } 713 break; 714 715 case APF_CHANNEL_WINDOW_ADJUST: 716 { 717 APF_WINDOW_ADJUST_MESSAGE *pMessage = 718 (APF_WINDOW_ADJUST_MESSAGE *)rxBuffer; 719 LMEChannelWindowAdjustMessage channelWindowAdjust; 720 721 channelWindowAdjust.RecipientChannel = ntohl(pMessage->RecipientChannel); 722 channelWindowAdjust.BytesToAdd = ntohl(pMessage->BytesToAdd); 723 _cb(_cbParam, &channelWindowAdjust, sizeof(channelWindowAdjust), &status); 724 } 725 break; 726 727 case APF_PROTOCOLVERSION: 728 { 729 APF_PROTOCOL_VERSION_MESSAGE *pMessage = 730 (APF_PROTOCOL_VERSION_MESSAGE *)rxBuffer; 731 LMEProtocolVersionMessage protVersion; 732 733 protVersion.MajorVersion = ntohl(pMessage->MajorVersion); 734 protVersion.MinorVersion = ntohl(pMessage->MinorVersion); 735 protVersion.TriggerReason = 736 (APF_TRIGGER_REASON)ntohl(pMessage->TriggerReason); 737 _cb(_cbParam, &protVersion, sizeof(protVersion), &status); 738 } 739 break; 740 741 default: 742 // Uknown request. Ignore 743 break; 744 } 745 746 if (IsInitialized()) { 747 plugin.postprocess(rxBuffer, bytesRead, status); 748 } 749 } 750 751 if (rxBuffer != NULL) { 752 delete[] rxBuffer; 753 } 754 } 755 756 void LMEConnection::_apfChannelOpen(unsigned char *rxBuffer, unsigned int bytesRead, int *status) 757 { 758 APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer; 759 760 if (_strnicmp((char *)pHeader->String, 761 APF_OPEN_CHANNEL_REQUEST_DIRECT, 762 APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT)) == 0) { 763 764 UINT32 senderChannel = 0; 765 766 _apfChannelOpenDirect(rxBuffer, bytesRead, &senderChannel, status); 767 if (IsInitialized() && (*status == 1)) { 768 if (plugin.retry(rxBuffer, bytesRead) != LMS_DROPPED) { 769 _apfChannelOpenDirect(rxBuffer, bytesRead, NULL, status); 770 } 771 } 772 if (IsInitialized() && (*status == 1)) { 773 ChannelOpenReplayFailure(senderChannel, 774 OPEN_FAILURE_REASON_CONNECT_FAILED); 775 } 776 } 777 } 778 779 void LMEConnection::_apfChannelOpenDirect(unsigned char *rxBuffer, unsigned int bytesRead, UINT32 *senderChannel, int *status) 780 { 781 unsigned char *pCurrent; 782 APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer; 783 784 if (bytesRead < sizeof(APF_GENERIC_HEADER) + 785 ntohl(pHeader->StringLength) + 786 7 + (5 * sizeof(UINT32))) { 787 PRINT("Error receiving data from HECI\n"); 788 Deinit(); 789 return; 790 } 791 792 pCurrent = rxBuffer + sizeof(APF_GENERIC_HEADER) + 793 APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT); 794 795 LMEChannelOpenRequestMessage channelOpenRequest; 796 channelOpenRequest.ChannelType = LMEChannelOpenRequestMessage::DIRECT; 797 798 channelOpenRequest.SenderChannel = ntohl(*((UINT32 *)pCurrent)); 799 if (senderChannel) { 800 *senderChannel = channelOpenRequest.SenderChannel; 801 } 802 pCurrent += sizeof(UINT32); 803 channelOpenRequest.InitialWindow = ntohl(*((UINT32 *)pCurrent)); 804 pCurrent += 2 * sizeof(UINT32); 805 806 UINT32 len = ntohl(*((UINT32 *)pCurrent)); 807 pCurrent += sizeof(UINT32); 808 channelOpenRequest.Address.append((char *)pCurrent, len); 809 pCurrent += len; 810 channelOpenRequest.Port = ntohl(*((UINT32 *)pCurrent)); 811 pCurrent += sizeof(UINT32); 812 813 _cb(_cbParam, &channelOpenRequest, sizeof(channelOpenRequest), status); 814 } 815 816 void LMEConnection::_apfGlobalRequest(unsigned char *rxBuffer, unsigned int bytesRead, int *status) 817 { 818 unsigned char *pCurrent; 819 APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer; 820 821 if (_strnicmp((char *)pHeader->String, 822 APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST, 823 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST)) == 0) { 824 LMETcpForwardRequestMessage tcpForwardRequest; 825 unsigned int hsize = sizeof(APF_GENERIC_HEADER) + 826 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_REQUEST) + 827 sizeof(UINT8); 828 pCurrent = rxBuffer + hsize; 829 bytesRead -= hsize; 830 831 if (bytesRead < sizeof(UINT32)) { 832 PRINT("Error receiving data from HECI\n"); 833 Deinit(); 834 return; 835 } 836 837 UINT32 len = ntohl(*((UINT32 *)pCurrent)); 838 pCurrent += sizeof(UINT32); 839 840 if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) { 841 PRINT("Error receiving data from HECI\n"); 842 Deinit(); 843 return; 844 } 845 846 tcpForwardRequest.Address.append((char *)pCurrent, len); 847 pCurrent += len; 848 tcpForwardRequest.Port = ntohl(*((UINT32 *)pCurrent)); 849 850 _cb(_cbParam, &tcpForwardRequest, sizeof(tcpForwardRequest), status); 851 } 852 else if (_strnicmp((char *)pHeader->String, 853 APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST, 854 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST)) == 0) { 855 LMETcpForwardCancelRequestMessage tcpForwardCancelRequest; 856 unsigned int hsize = sizeof(APF_GENERIC_HEADER) + 857 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_TCP_FORWARD_CANCEL_REQUEST) + 858 sizeof(UINT8); 859 pCurrent = rxBuffer + hsize; 860 bytesRead -= hsize; 861 862 if (bytesRead < sizeof(UINT32)) { 863 PRINT("Error receiving data from HECI\n"); 864 Deinit(); 865 return; 866 } 867 868 UINT32 len = ntohl(*((UINT32 *)pCurrent)); 869 pCurrent += sizeof(UINT32); 870 871 if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) { 872 PRINT("Error receiving data from HECI\n"); 873 Deinit(); 874 return; 875 } 876 877 tcpForwardCancelRequest.Address.append((char *)pCurrent, len); 878 pCurrent += len; 879 tcpForwardCancelRequest.Port = ntohl(*((UINT32 *)pCurrent)); 880 881 _cb(_cbParam, &tcpForwardCancelRequest, sizeof(tcpForwardCancelRequest), status); 882 } 883 else if (_strnicmp((char *)pHeader->String, 884 APF_GLOBAL_REQUEST_STR_UDP_SEND_TO, 885 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO)) == 0) { 886 unsigned int hsize = sizeof(APF_GENERIC_HEADER) + 887 APF_STR_SIZE_OF(APF_GLOBAL_REQUEST_STR_UDP_SEND_TO) + 888 sizeof(UINT8); 889 pCurrent = rxBuffer + hsize; 890 bytesRead -= hsize; 891 892 if (bytesRead < sizeof(UINT32)) { 893 PRINT("Error receiving data from HECI\n"); 894 Deinit(); 895 return; 896 } 897 898 UINT32 len = ntohl(*((UINT32 *)pCurrent)); 899 pCurrent += sizeof(UINT32); 900 901 if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) { 902 PRINT("Error receiving data from HECI\n"); 903 Deinit(); 904 return; 905 } 906 bytesRead -= (sizeof(UINT32) + len + sizeof(UINT32)); 907 908 std::string address; 909 address.append((char *)pCurrent, len); 910 pCurrent += len; 911 UINT32 port = ntohl(*((UINT32 *)pCurrent)); 912 pCurrent += sizeof(UINT32); 913 914 if (bytesRead < sizeof(UINT32)) { 915 PRINT("Error receiving data from HECI\n"); 916 Deinit(); 917 return; 918 } 919 920 // Skip Originator IP and Port 921 len = ntohl(*((UINT32 *)pCurrent)); 922 pCurrent += sizeof(UINT32); 923 924 if (bytesRead < (sizeof(UINT32) + len + sizeof(UINT32))) { 925 PRINT("Error receiving data from HECI\n"); 926 Deinit(); 927 return; 928 } 929 bytesRead -= (sizeof(UINT32) + len + sizeof(UINT32)); 930 931 pCurrent += len; 932 pCurrent += sizeof(UINT32); 933 934 if (bytesRead < sizeof(UINT32)) { 935 PRINT("Error receiving data from HECI\n"); 936 Deinit(); 937 return; 938 } 939 940 // Retrieve Data 941 len = ntohl(*((UINT32 *)pCurrent)); 942 pCurrent += sizeof(UINT32); 943 944 if (bytesRead < (sizeof(UINT32) + len)) { 945 PRINT("Error receiving data from HECI\n"); 946 Deinit(); 947 return; 948 } 949 950 LMEUdpSendToMessage udpSendTo(address, port, len, pCurrent); 951 952 _cb(_cbParam, &udpSendTo, sizeof(udpSendTo), status); 953 } 954 } 955 956 void LMEConnection::_apfUserAuthRequest(unsigned char *rxBuffer, unsigned int bytesRead, int *status) 957 { 958 unsigned char *pCurrent = rxBuffer; 959 960 ++pCurrent; 961 962 LMEUserAuthRequestMessage userAuthRequest; 963 964 UINT32 len = ntohl(*((UINT32 *)pCurrent)); 965 pCurrent += sizeof(UINT32); 966 967 if ((bytesRead - (pCurrent - rxBuffer)) < len) { 968 PRINT("Error receiving data from HECI\n"); 969 Deinit(); 970 return; 971 } 972 973 userAuthRequest.Username.append((char *)pCurrent, len); 974 pCurrent += len; 975 976 if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32)) { 977 PRINT("Error receiving data from HECI\n"); 978 Deinit(); 979 return; 980 } 981 982 len = ntohl(*((UINT32 *)pCurrent)); 983 pCurrent += sizeof(UINT32); 984 985 if ((bytesRead - (pCurrent - rxBuffer)) < len) { 986 PRINT("Error receiving data from HECI\n"); 987 Deinit(); 988 return; 989 } 990 991 userAuthRequest.ServiceName.append((char *)pCurrent, len); 992 pCurrent += len; 993 994 if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32)) { 995 PRINT("Error receiving data from HECI\n"); 996 Deinit(); 997 return; 998 } 999 1000 len = ntohl(*((UINT32 *)pCurrent)); 1001 pCurrent += sizeof(UINT32); 1002 1003 if ((bytesRead - (pCurrent - rxBuffer)) < len) { 1004 PRINT("Error receiving data from HECI\n"); 1005 Deinit(); 1006 return; 1007 } 1008 1009 userAuthRequest.MethodName.append((char *)pCurrent, len); 1010 pCurrent += len; 1011 1012 if (_strnicmp(userAuthRequest.MethodName.c_str(), APF_AUTH_PASSWORD, 1013 userAuthRequest.MethodName.size()) == 0) { 1014 1015 if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(UINT32) + 1) { 1016 PRINT("Error receiving data from HECI\n"); 1017 Deinit(); 1018 return; 1019 } 1020 1021 ++pCurrent; 1022 1023 len = ntohl(*((UINT32 *)pCurrent)); 1024 pCurrent += sizeof(UINT32); 1025 1026 if ((bytesRead - (pCurrent - rxBuffer)) < len) { 1027 PRINT("Error receiving data from HECI\n"); 1028 Deinit(); 1029 return; 1030 } 1031 1032 AuthPasswordData authData; 1033 authData.Password.append((char *)pCurrent, len); 1034 pCurrent += len; 1035 1036 userAuthRequest.MethodData = &authData; 1037 } 1038 1039 _cb(_cbParam, &userAuthRequest, sizeof(userAuthRequest), status); 1040 } 1041 1042 unsigned int LMEConnection::GetHeciBufferSize() const 1043 { 1044 if (_pHeci == NULL) { 1045 return 0; 1046 } 1047 return _pHeci->GetBufferSize(); 1048 } 1049 1050