TURN Server
1.5
|
00001 /* 00002 * Copyright (C) 2012, 2013 Citrix Systems 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. Neither the name of the project nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00024 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00025 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00027 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 */ 00030 00031 #ifndef __LIB_TURN_MSG_CPP__ 00032 #define __LIB_TURN_MSG_CPP__ 00033 00034 #include "ns_turn_ioaddr.h" 00035 #include "ns_turn_msg.h" 00036 00037 #include <string> 00038 00039 namespace turn { 00040 00041 class StunAttr; 00042 00046 class EndOfStunMsgException { 00047 public: 00048 EndOfStunMsgException() {} 00049 virtual ~EndOfStunMsgException() {} 00050 }; 00051 00055 class WrongStunAttrFormatException { 00056 public: 00057 WrongStunAttrFormatException() {} 00058 virtual ~WrongStunAttrFormatException() {} 00059 }; 00060 00064 class WrongStunBufferFormatException { 00065 public: 00066 WrongStunBufferFormatException() {} 00067 virtual ~WrongStunBufferFormatException() {} 00068 }; 00069 00073 class StunAttrIterator { 00074 public: 00078 StunAttrIterator(u08bits *buf, size_t sz) throw (WrongStunBufferFormatException) : 00079 _buf(buf), _sz(sz) { 00080 if(!stun_is_command_message_str(_buf, _sz)) { 00081 throw WrongStunBufferFormatException(); 00082 } 00083 _sar = stun_attr_get_first_str(_buf, _sz); 00084 } 00085 00089 template<class T> 00090 StunAttrIterator(T &msg) throw (WrongStunBufferFormatException) : 00091 _buf(msg.getRawBuffer()), _sz(msg.getSize()) { 00092 if(!stun_is_command_message_str(_buf, _sz)) { 00093 throw WrongStunBufferFormatException(); 00094 } 00095 _sar = stun_attr_get_first_str(_buf, _sz); 00096 } 00097 00102 StunAttrIterator(u08bits *buf, size_t sz, u16bits attr_type) throw (WrongStunBufferFormatException) : 00103 _buf(buf), _sz(sz) { 00104 if(!stun_is_command_message_str(_buf, _sz)) { 00105 throw WrongStunBufferFormatException(); 00106 } 00107 _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); 00108 } 00109 00114 template<class T> 00115 StunAttrIterator(T &msg, u16bits attr_type) throw (WrongStunBufferFormatException) : 00116 _buf(msg.getRawBuffer()), _sz(msg.getSize()) { 00117 if(!stun_is_command_message_str(_buf, _sz)) { 00118 throw WrongStunBufferFormatException(); 00119 } 00120 _sar = stun_attr_get_first_by_type_str(_buf, _sz, attr_type); 00121 } 00122 00126 void next() throw(EndOfStunMsgException) { 00127 if(!_sar) { 00128 throw EndOfStunMsgException(); 00129 } 00130 _sar = stun_attr_get_next_str(_buf,_sz,_sar); 00131 } 00132 00136 bool eof() const { 00137 return (!_sar); 00138 } 00139 00143 bool isAddr() const { 00144 return stun_attr_is_addr(_sar); 00145 } 00146 00150 int getAddressFamily() const { 00151 return stun_get_requested_address_family(_sar); 00152 } 00153 00157 int getType() const { 00158 return stun_attr_get_type(_sar); 00159 } 00160 00164 virtual ~StunAttrIterator() {} 00165 00170 const u08bits *getRawBuffer(size_t &sz) const throw(WrongStunAttrFormatException) { 00171 int len = stun_attr_get_len(_sar); 00172 if(len<0) 00173 throw WrongStunAttrFormatException(); 00174 sz = (size_t)len; 00175 const u08bits *value = stun_attr_get_value(_sar); 00176 return value; 00177 } 00178 friend class StunAttr; 00179 private: 00180 u08bits *_buf; 00181 size_t _sz; 00182 stun_attr_ref _sar; 00183 }; 00184 00189 class StunAttr { 00190 public: 00194 StunAttr() : _attr_type(0), _value(0), _sz(0) {} 00195 00199 StunAttr(const StunAttrIterator &iter) throw(WrongStunAttrFormatException, EndOfStunMsgException) { 00200 if(iter.eof()) { 00201 throw EndOfStunMsgException(); 00202 } 00203 size_t sz = 0; 00204 const u08bits *ptr = iter.getRawBuffer(sz); 00205 if(sz>=0xFFFF) 00206 throw WrongStunAttrFormatException(); 00207 int at = iter.getType(); 00208 if(at<0) 00209 throw WrongStunAttrFormatException(); 00210 _attr_type = (u16bits)at; 00211 _sz = sz; 00212 _value=(u08bits*)turn_malloc(_sz); 00213 if(ptr) 00214 ns_bcopy(ptr,_value,_sz); 00215 } 00216 00220 virtual ~StunAttr() { 00221 if(_value) 00222 turn_free(_value,_sz); 00223 } 00224 00228 const u08bits *getRawValue(size_t &sz) const { 00229 sz=_sz; 00230 return _value; 00231 } 00232 00236 void setRawValue(u08bits *value, size_t sz) throw(WrongStunAttrFormatException) { 00237 if(sz>0xFFFF) 00238 throw WrongStunAttrFormatException(); 00239 if(_value) 00240 turn_free(_value,_sz); 00241 _sz = sz; 00242 _value=(u08bits*)turn_malloc(_sz); 00243 if(value) 00244 ns_bcopy(value,_value,_sz); 00245 } 00246 00250 u16bits getType() const { 00251 return _attr_type; 00252 } 00253 00257 void setType(u16bits at) { 00258 _attr_type = at; 00259 } 00260 00264 template<class T> 00265 int addToMsg(T &msg) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00266 if(!_attr_type) 00267 throw WrongStunAttrFormatException(); 00268 u08bits *buffer = msg.getRawBuffer(); 00269 if(buffer) { 00270 size_t sz = msg.getSize(); 00271 if(addToBuffer(buffer, sz)<0) { 00272 throw WrongStunBufferFormatException(); 00273 } 00274 msg.setSize(sz); 00275 return 0; 00276 } 00277 throw WrongStunBufferFormatException(); 00278 } 00279 protected: 00280 00284 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00285 if(buffer) { 00286 if(!_value) 00287 throw WrongStunAttrFormatException(); 00288 if(stun_attr_add_str(buffer, &sz, _attr_type, _value, _sz)<0) { 00289 throw WrongStunBufferFormatException(); 00290 } 00291 return 0; 00292 } 00293 throw WrongStunBufferFormatException(); 00294 } 00295 00299 static stun_attr_ref getSar(const StunAttrIterator &iter) { 00300 return iter._sar; 00301 } 00302 private: 00303 u16bits _attr_type; 00304 u08bits *_value; 00305 size_t _sz; 00306 }; 00307 00311 class StunAttrChannelNumber : public StunAttr { 00312 public: 00313 StunAttrChannelNumber() : _cn(0) { 00314 setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); 00315 } 00316 StunAttrChannelNumber(const StunAttrIterator &iter) 00317 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00318 StunAttr(iter) { 00319 00320 if(iter.eof()) 00321 throw EndOfStunMsgException(); 00322 _cn = stun_attr_get_channel_number(getSar(iter)); 00323 if(!_cn) 00324 throw WrongStunAttrFormatException(); 00325 } 00326 virtual ~StunAttrChannelNumber() {} 00327 u16bits getChannelNumber() const { 00328 return _cn; 00329 } 00330 void setChannelNumber(u16bits cn) { 00331 _cn = cn; 00332 } 00333 protected: 00334 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00335 return stun_attr_add_channel_number_str(buffer,&sz,_cn); 00336 } 00337 private: 00338 u16bits _cn; 00339 }; 00340 00344 class StunAttrEvenPort : public StunAttr { 00345 public: 00346 StunAttrEvenPort() : _ep(0) { 00347 setType(STUN_ATTRIBUTE_EVEN_PORT); 00348 } 00349 StunAttrEvenPort(const StunAttrIterator &iter) 00350 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00351 StunAttr(iter) { 00352 00353 if(iter.eof()) 00354 throw EndOfStunMsgException(); 00355 _ep = stun_attr_get_even_port(getSar(iter)); 00356 } 00357 virtual ~StunAttrEvenPort() {} 00358 u08bits getEvenPort() const { 00359 return _ep; 00360 } 00361 void setEvenPort(u08bits ep) { 00362 _ep = ep; 00363 } 00364 protected: 00365 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00366 return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1); 00367 } 00368 private: 00369 u08bits _ep; 00370 }; 00371 00375 class StunAttrReservationToken : public StunAttr { 00376 public: 00377 StunAttrReservationToken() : _rt(0) { 00378 setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); 00379 } 00380 StunAttrReservationToken(const StunAttrIterator &iter) 00381 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00382 StunAttr(iter) { 00383 00384 if(iter.eof()) 00385 throw EndOfStunMsgException(); 00386 _rt = stun_attr_get_reservation_token_value(getSar(iter)); 00387 } 00388 virtual ~StunAttrReservationToken() {} 00389 u64bits getReservationToken() const { 00390 return _rt; 00391 } 00392 void setReservationToken(u64bits rt) { 00393 _rt = rt; 00394 } 00395 protected: 00396 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00397 uint64_t reservation_token = ioa_ntoh64(_rt); 00398 return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (u08bits*) (&reservation_token), 8); 00399 } 00400 private: 00401 u64bits _rt; 00402 }; 00403 00407 class StunAttrAddr : public StunAttr { 00408 public: 00409 StunAttrAddr(u16bits attr_type = 0) { 00410 addr_set_any(&_addr); 00411 setType(attr_type); 00412 } 00413 StunAttrAddr(const StunAttrIterator &iter) 00414 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00415 StunAttr(iter) { 00416 00417 if(iter.eof()) 00418 throw EndOfStunMsgException(); 00419 size_t sz = 0; 00420 const u08bits *buf = iter.getRawBuffer(sz); 00421 if(stun_attr_get_addr_str(buf,sz,getSar(iter),&_addr,NULL)<0) { 00422 throw WrongStunAttrFormatException(); 00423 } 00424 } 00425 virtual ~StunAttrAddr() {} 00426 void getAddr(ioa_addr &addr) const { 00427 addr_cpy(&addr,&_addr); 00428 } 00429 void setAddr(ioa_addr &addr) { 00430 addr_cpy(&_addr,&addr); 00431 } 00432 protected: 00433 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00434 return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr); 00435 } 00436 private: 00437 ioa_addr _addr; 00438 }; 00439 00443 class StunAttrChangeRequest : public StunAttr { 00444 public: 00445 StunAttrChangeRequest() : _changeIp(0), _changePort(0) { 00446 setType(STUN_ATTRIBUTE_CHANGE_REQUEST); 00447 } 00448 StunAttrChangeRequest(const StunAttrIterator &iter) 00449 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00450 StunAttr(iter) { 00451 00452 if(iter.eof()) 00453 throw EndOfStunMsgException(); 00454 00455 if(stun_attr_get_change_request_str(getSar(iter), &_changeIp, &_changePort)<0) { 00456 throw WrongStunAttrFormatException(); 00457 } 00458 } 00459 virtual ~StunAttrChangeRequest() {} 00460 bool getChangeIp() const { 00461 return _changeIp; 00462 } 00463 void setChangeIp(bool ci) { 00464 if(ci) 00465 _changeIp = 1; 00466 else 00467 _changeIp = 0; 00468 } 00469 bool getChangePort() const { 00470 return _changePort; 00471 } 00472 void setChangePort(bool cp) { 00473 if(cp) 00474 _changePort = 1; 00475 else 00476 _changePort = 0; 00477 } 00478 protected: 00479 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00480 return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort); 00481 } 00482 private: 00483 int _changeIp; 00484 int _changePort; 00485 }; 00486 00490 class StunAttrResponsePort : public StunAttr { 00491 public: 00492 StunAttrResponsePort() : _rp(0) { 00493 setType(STUN_ATTRIBUTE_RESPONSE_PORT); 00494 } 00495 StunAttrResponsePort(const StunAttrIterator &iter) 00496 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00497 StunAttr(iter) { 00498 00499 if(iter.eof()) 00500 throw EndOfStunMsgException(); 00501 00502 int rp = stun_attr_get_response_port_str(getSar(iter)); 00503 if(rp<0) { 00504 throw WrongStunAttrFormatException(); 00505 } 00506 _rp = (u16bits)rp; 00507 } 00508 virtual ~StunAttrResponsePort() {} 00509 u16bits getResponsePort() const { 00510 return _rp; 00511 } 00512 void setResponsePort(u16bits p) { 00513 _rp = p; 00514 } 00515 protected: 00516 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00517 return stun_attr_add_response_port_str(buffer, &sz, _rp); 00518 } 00519 private: 00520 u16bits _rp; 00521 }; 00522 00526 class StunAttrPadding : public StunAttr { 00527 public: 00528 StunAttrPadding() : _p(0) { 00529 setType(STUN_ATTRIBUTE_PADDING); 00530 } 00531 StunAttrPadding(const StunAttrIterator &iter) 00532 throw(WrongStunAttrFormatException, EndOfStunMsgException) : 00533 StunAttr(iter) { 00534 00535 if(iter.eof()) 00536 throw EndOfStunMsgException(); 00537 00538 int p = stun_attr_get_padding_len_str(getSar(iter)); 00539 if(p<0) { 00540 throw WrongStunAttrFormatException(); 00541 } 00542 _p = (u16bits)p; 00543 } 00544 virtual ~StunAttrPadding() {} 00545 u16bits getPadding() const { 00546 return _p; 00547 } 00551 void setPadding(u16bits p) { 00552 _p = p; 00553 } 00554 protected: 00555 virtual int addToBuffer(u08bits *buffer, size_t &sz) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00556 return stun_attr_add_padding_str(buffer, &sz, _p); 00557 } 00558 private: 00559 u16bits _p; 00560 }; 00561 00565 class StunMsg { 00566 public: 00570 StunMsg() { 00571 _allocated_sz = 0xFFFF; 00572 _buffer = (u08bits*)turn_malloc(_allocated_sz); 00573 _deallocate = true; 00574 _sz = 0; 00575 _constructed = 0; 00576 } 00577 00582 StunMsg(u08bits *buffer, size_t total_sz, size_t sz, bool constructed) : 00583 _buffer(buffer), _deallocate(false), _allocated_sz(total_sz), 00584 _sz(sz), _constructed(constructed) {} 00585 00589 virtual ~StunMsg() { 00590 if(_deallocate && _buffer) { 00591 turn_free(_buffer, _allocated_sz); 00592 } 00593 } 00594 00598 void construct() { 00599 constructBuffer(); 00600 } 00601 00605 bool isValid() { 00606 return check(); 00607 } 00608 00612 u08bits *getRawBuffer() { 00613 return _buffer; 00614 } 00615 00619 size_t getSize() const { 00620 return _sz; 00621 } 00622 00626 void setSize(size_t sz) throw(WrongStunBufferFormatException) { 00627 if(sz>_allocated_sz) 00628 throw WrongStunBufferFormatException(); 00629 _sz = sz; 00630 } 00631 00635 static bool isCommand(u08bits *buffer, size_t sz) { 00636 return stun_is_command_message_str(buffer, sz); 00637 } 00638 00642 bool isCommand() const { 00643 return stun_is_command_message_str(_buffer, _sz); 00644 } 00645 00646 static bool isIndication(u08bits *buffer, size_t sz) { 00647 return stun_is_indication_str(buffer, sz); 00648 } 00649 00650 static bool isRequest(u08bits *buffer, size_t sz) { 00651 return stun_is_request_str(buffer, sz); 00652 } 00653 00654 static bool isSuccessResponse(u08bits *buffer, size_t sz) { 00655 return stun_is_success_response_str(buffer, sz); 00656 } 00657 00658 static bool isErrorResponse(u08bits *buffer, size_t sz, 00659 int &err_code, u08bits *err_msg, size_t err_msg_size) { 00660 return stun_is_error_response_str(buffer, sz, &err_code, err_msg, err_msg_size); 00661 } 00662 00666 static bool isChallengeResponse(const u08bits* buf, size_t sz, 00667 int &err_code, u08bits *err_msg, size_t err_msg_size, 00668 u08bits *realm, u08bits *nonce) { 00669 return stun_is_challenge_response_str(buf, sz, &err_code, err_msg, err_msg_size, realm, nonce); 00670 } 00671 00675 static bool isChannel(u08bits *buffer, size_t sz) { 00676 return is_channel_msg_str(buffer, sz); 00677 } 00678 00682 static bool isFingerprintPresent(u08bits *buffer, size_t sz) { 00683 if(!stun_is_command_message_str(buffer,sz)) 00684 return false; 00685 stun_attr_ref sar = stun_attr_get_first_by_type_str(buffer, sz, STUN_ATTRIBUTE_FINGERPRINT); 00686 if(!sar) 00687 return false; 00688 00689 return true; 00690 } 00691 00695 static bool checkFingerprint(u08bits *buffer, size_t sz) { 00696 return stun_is_command_message_full_check_str(buffer, sz, 1); 00697 } 00698 00702 int addAttr(StunAttr &attr) throw(WrongStunAttrFormatException, WrongStunBufferFormatException) { 00703 return attr.addToMsg(*this); 00704 } 00705 00709 virtual stun_tid getTid() const throw(WrongStunBufferFormatException) { 00710 if(!_constructed || !isCommand()) 00711 throw WrongStunBufferFormatException(); 00712 stun_tid tid; 00713 stun_tid_from_message_str(_buffer,_sz,&tid); 00714 return tid; 00715 } 00716 00720 virtual void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { 00721 if(!_constructed || !isCommand()) 00722 throw WrongStunBufferFormatException(); 00723 stun_tid_message_cpy(_buffer, &tid); 00724 } 00725 00729 void addFingerprint() throw(WrongStunBufferFormatException) { 00730 if(!_constructed || !isCommand()) 00731 throw WrongStunBufferFormatException(); 00732 stun_attr_add_fingerprint_str(_buffer,&_sz); 00733 } 00734 00738 bool checkMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd) const 00739 throw(WrongStunBufferFormatException) { 00740 if(!_constructed || !isCommand()) 00741 throw WrongStunBufferFormatException(); 00742 return (0 == stun_check_message_integrity_str(_buffer, _sz, 00743 (u08bits *)uname.c_str(), (u08bits *)realm.c_str(), (u08bits *)upwd.c_str())); 00744 } 00745 00749 void addMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) 00750 throw(WrongStunBufferFormatException) { 00751 00752 if(!_constructed || !isCommand()) 00753 throw WrongStunBufferFormatException(); 00754 00755 stun_attr_add_integrity_by_user_str(_buffer, &_sz, 00756 (u08bits *)uname.c_str(), (u08bits *)realm.c_str(), (u08bits *)upwd.c_str(), (u08bits *)nonce.c_str()); 00757 } 00758 00759 protected: 00760 virtual void constructBuffer() = 0; 00761 virtual bool check() = 0; 00762 protected: 00763 u08bits *_buffer; 00764 bool _deallocate; 00765 size_t _allocated_sz; 00766 size_t _sz; 00767 bool _constructed; 00768 }; 00769 00773 class StunMsgRequest : public StunMsg { 00774 public: 00775 StunMsgRequest(u16bits method) : _method(method) {}; 00776 StunMsgRequest(u08bits *buffer, size_t total_sz, size_t sz, bool constructed) 00777 throw(WrongStunBufferFormatException) : 00778 StunMsg(buffer,total_sz,sz,constructed),_method(0) { 00779 00780 if(constructed) { 00781 if(!stun_is_request_str(buffer,sz)) { 00782 throw WrongStunBufferFormatException(); 00783 } 00784 _method = stun_get_method_str(buffer,sz); 00785 } 00786 } 00787 virtual ~StunMsgRequest() {} 00788 00792 u16bits getMethod() const { 00793 return _method; 00794 } 00795 00799 void setMethod(u16bits method) { 00800 _method = method; 00801 } 00802 00806 void constructBindingRequest() { 00807 stun_set_binding_request_str(_buffer, &_sz); 00808 } 00809 00810 bool isBindingRequest() const { 00811 return stun_is_binding_request_str(_buffer,_sz,0); 00812 } 00813 00817 void constructAllocateRequest(u32bits lifetime, int address_family) { 00818 stun_set_allocate_request_str(_buffer, &_sz, lifetime, address_family); 00819 } 00820 00824 void constructChannelBindRequest(const ioa_addr &peer_addr, u16bits channel_number) { 00825 stun_set_channel_bind_request_str(_buffer, &_sz, 00826 &peer_addr, channel_number); 00827 } 00828 00829 protected: 00830 virtual void constructBuffer() { 00831 stun_init_request_str(_method,_buffer,&_sz); 00832 _constructed = true; 00833 } 00834 00835 virtual bool check() { 00836 if(!_constructed) 00837 return false; 00838 if(!stun_is_request_str(_buffer,_sz)) { 00839 return false; 00840 } 00841 if(_method != stun_get_method_str(_buffer,_sz)) { 00842 return false; 00843 } 00844 return true; 00845 } 00846 00847 private: 00848 u16bits _method; 00849 }; 00850 00854 class StunMsgResponse : public StunMsg { 00855 public: 00856 StunMsgResponse(u16bits method, stun_tid &tid) : _method(method), _err(0), _reason(""), _tid(tid) {}; 00857 StunMsgResponse(u16bits method, int error_code, std::string reason, stun_tid &tid) : 00858 _method(method), _err(error_code), _reason(reason), _tid(tid) { 00859 00860 }; 00861 StunMsgResponse(u08bits *buffer, size_t total_sz, size_t sz, bool constructed) 00862 throw(WrongStunBufferFormatException) : 00863 StunMsg(buffer,total_sz,sz,constructed),_method(0),_err(0),_reason("") { 00864 00865 if(constructed) { 00866 if(!stun_is_success_response_str(buffer,sz)) { 00867 u08bits errtxt[0xFFFF]; 00868 if(!stun_is_error_response_str(buffer,sz,&_err,errtxt,sizeof(errtxt))) { 00869 throw WrongStunBufferFormatException(); 00870 } 00871 _reason = (char*)errtxt; 00872 } 00873 _method = stun_get_method_str(buffer,sz); 00874 stun_tid_from_message_str(_buffer,_sz,&_tid); 00875 } 00876 } 00877 00878 u16bits getMethod() const { 00879 return _method; 00880 } 00881 00882 void setMethod(u16bits method) { 00883 _method = method; 00884 } 00885 00889 int getError() const { 00890 return _err; 00891 } 00892 00896 void setError(int err) { 00897 _err = err; 00898 } 00899 00903 std::string getReason() const { 00904 return _reason; 00905 } 00906 00910 void setReason(std::string reason) { 00911 _reason = reason; 00912 } 00913 00917 void setTid(stun_tid &tid) throw(WrongStunBufferFormatException) { 00918 _tid = tid; 00919 } 00920 00924 stun_tid getTid() throw(WrongStunBufferFormatException) { 00925 return _tid; 00926 } 00927 00931 bool isChallenge(std::string &realm, std::string &nonce) const { 00932 bool ret = false; 00933 if(_constructed) { 00934 int err_code; 00935 u08bits err_msg[1025]; 00936 size_t err_msg_size=sizeof(err_msg); 00937 u08bits srealm[0xFFFF]; 00938 u08bits snonce[0xFFFF]; 00939 ret = stun_is_challenge_response_str(_buffer, _sz, &err_code, err_msg, err_msg_size, srealm, snonce); 00940 if(ret) { 00941 realm = (char*)srealm; 00942 nonce = (char*)snonce; 00943 } 00944 } 00945 return ret; 00946 } 00947 00948 bool isChallenge() const { 00949 std::string realm, nonce; 00950 return isChallenge(realm, nonce); 00951 } 00952 00956 bool isSuccess() const { 00957 return (_err == 0); 00958 } 00959 00963 void constructBindingResponse(stun_tid &tid, 00964 const ioa_addr &reflexive_addr, int error_code, 00965 const u08bits *reason) { 00966 00967 stun_set_binding_response_str(_buffer, &_sz, &tid, 00968 &reflexive_addr, error_code, 00969 reason); 00970 } 00971 00972 bool isBindingResponse() const { 00973 return stun_is_binding_response_str(_buffer,_sz); 00974 } 00975 00979 void constructAllocateResponse(stun_tid &tid, 00980 const ioa_addr &relayed_addr, 00981 const ioa_addr &reflexive_addr, 00982 u32bits lifetime, int error_code, const u08bits *reason, 00983 u64bits reservation_token) { 00984 00985 stun_set_allocate_response_str(_buffer, &_sz, &tid, 00986 &relayed_addr, 00987 &reflexive_addr, 00988 lifetime, error_code, reason, 00989 reservation_token); 00990 } 00991 00995 void constructChannelBindResponse(stun_tid &tid, int error_code, const u08bits *reason) { 00996 stun_set_channel_bind_response_str(_buffer, &_sz, &tid, error_code, reason); 00997 } 00998 00999 protected: 01000 virtual void constructBuffer() { 01001 if(_err) { 01002 stun_init_error_response_str(_method, _buffer, &_sz, _err, (u08bits*)_reason.c_str(), &_tid); 01003 } else { 01004 stun_init_success_response_str(_method, _buffer, &_sz, &_tid); 01005 } 01006 _constructed = true; 01007 } 01008 01009 virtual bool check() { 01010 if(!_constructed) 01011 return false; 01012 if(!stun_is_success_response_str(_buffer,_sz)) { 01013 u08bits errtxt[0xFFFF]; 01014 int cerr=0; 01015 if(!stun_is_error_response_str(_buffer,_sz,&cerr,errtxt,sizeof(errtxt))) { 01016 throw WrongStunBufferFormatException(); 01017 } 01018 if(cerr != _err) { 01019 throw WrongStunBufferFormatException(); 01020 } 01021 } 01022 if(_method != stun_get_method_str(_buffer,_sz)) { 01023 return false; 01024 } 01025 return true; 01026 } 01027 01028 private: 01029 u16bits _method; 01030 int _err; 01031 std::string _reason; 01032 stun_tid _tid; 01033 }; 01034 01038 class StunMsgIndication : public StunMsg { 01039 public: 01040 StunMsgIndication(u16bits method) : _method(method) {}; 01041 StunMsgIndication(u08bits *buffer, size_t total_sz, size_t sz, bool constructed) 01042 throw(WrongStunBufferFormatException) : 01043 StunMsg(buffer,total_sz,sz,constructed),_method(0) { 01044 01045 if(constructed) { 01046 if(!stun_is_indication_str(buffer,sz)) { 01047 throw WrongStunBufferFormatException(); 01048 } 01049 _method = stun_get_method_str(buffer,sz); 01050 } 01051 } 01052 virtual ~StunMsgIndication() {} 01053 01054 u16bits getMethod() const { 01055 return _method; 01056 } 01057 01058 void setMethod(u16bits method) { 01059 _method = method; 01060 } 01061 01062 protected: 01063 virtual void constructBuffer() { 01064 stun_init_indication_str(_method,_buffer,&_sz); 01065 _constructed = true; 01066 } 01067 01068 virtual bool check() { 01069 if(!_constructed) 01070 return false; 01071 if(!stun_is_indication_str(_buffer,_sz)) { 01072 return false; 01073 } 01074 if(_method != stun_get_method_str(_buffer,_sz)) { 01075 return false; 01076 } 01077 return true; 01078 } 01079 01080 private: 01081 u16bits _method; 01082 }; 01083 01087 class StunMsgChannel : public StunMsg { 01088 public: 01089 StunMsgChannel(u16bits cn, int length) : _cn(cn), _len(length) {}; 01090 StunMsgChannel(u08bits *buffer, size_t total_sz, size_t sz, bool constructed) 01091 throw(WrongStunBufferFormatException) : 01092 StunMsg(buffer,total_sz,sz,constructed),_cn(0) { 01093 01094 if(constructed) { 01095 if(!stun_is_channel_message_str(buffer,sz,&_cn)) { 01096 throw WrongStunBufferFormatException(); 01097 } 01098 if(_sz>0xFFFF || _sz<4) 01099 throw WrongStunBufferFormatException(); 01100 01101 _len = _sz-4; 01102 } else { 01103 if(total_sz>0xFFFF || total_sz<4) 01104 throw WrongStunBufferFormatException(); 01105 01106 _len = 0; 01107 } 01108 } 01109 virtual ~StunMsgChannel() {} 01110 01111 u16bits getChannelNumber() const { 01112 return _cn; 01113 } 01114 01115 void setChannelNumber(u16bits cn) { 01116 _cn = cn; 01117 } 01118 01122 size_t getLength() const { 01123 return _len; 01124 } 01125 01129 void setLength(size_t len) { 01130 _len = len; 01131 } 01132 01133 protected: 01134 virtual void constructBuffer() { 01135 stun_init_channel_message_str(_cn,_buffer,&_sz,(int)_len); 01136 _constructed = true; 01137 } 01138 01139 virtual bool check() { 01140 if(!_constructed) 01141 return false; 01142 u16bits cn = 0; 01143 if(!stun_is_channel_message_str(_buffer,_sz,&cn)) { 01144 return false; 01145 } 01146 if(_cn != cn) { 01147 return false; 01148 } 01149 return true; 01150 } 01151 01152 private: 01153 u16bits _cn; 01154 size_t _len; 01155 }; 01156 01157 }; 01158 /* namespace */ 01159 01160 #endif 01161 /* __LIB_TURN_MSG_CPP__ */