Stun Server  Compliant with the latest RFCs including 5389, 5769, and 5780
discover the local host's own external IP address
testreader.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2011 John Selbie
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 
17 
18 
19 #include "commonincludes.hpp"
20 #include "stuncore.h"
21 
22 #include "testreader.h"
23 
24 
25 // the following request block is from RFC 5769, section 2.1
26 // static
27 const unsigned char c_requestbytes[] =
28  "\x00\x01\x00\x58"
29  "\x21\x12\xa4\x42"
30  "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae"
31  "\x80\x22\x00\x10"
32  "STUN test client"
33  "\x00\x24\x00\x04"
34  "\x6e\x00\x01\xff"
35  "\x80\x29\x00\x08"
36  "\x93\x2f\xf9\xb1\x51\x26\x3b\x36"
37  "\x00\x06\x00\x09"
38  "\x65\x76\x74\x6a\x3a\x68\x36\x76\x59\x20\x20\x20"
39  "\x00\x08\x00\x14"
40  "\x9a\xea\xa7\x0c\xbf\xd8\xcb\x56\x78\x1e\xf2\xb5"
41  "\xb2\xd3\xf2\x49\xc1\xb5\x71\xa2"
42  "\x80\x28\x00\x04"
43  "\xe5\x7a\x3b\xcf";
44 
45 const char c_password[] = "VOkJxbRl1RmTxUk/WvJxBt";
46 const char c_username[] = "evtj:h6vY";
47 const char c_software[] = "STUN test client";
48 
49 
51 {
52  HRESULT hr = S_OK;
53  Chk(Test1());
54  Chk(Test2());
55 Cleanup:
56  return hr;
57 }
58 
59 
61 {
62  HRESULT hr = S_OK;
63 
64  StunAttribute attrib;
65  CRefCountedBuffer spBuffer;
66  char szStringValue[100];
67 
68  const unsigned char *req = c_requestbytes;
69  size_t requestsize = sizeof(c_requestbytes)-1; // -1 to get rid of the trailing null
70 
71  CStunMessageReader reader;
73 
74  // reader is expecting at least enough bytes to fill the header
77 
78  state = reader.AddBytes(req, requestsize);
80 
81  ChkIfA(reader.HowManyBytesNeeded() != 0, E_FAIL);
82 
83  ChkA(reader.GetBuffer(&spBuffer));
84 
86 
88 
90 
92 
93  ChkIfA(0 != ::strncmp(c_software, (const char*)(spBuffer->GetData() + attrib.offset), attrib.size), E_FAIL);
94 
96 
98 
99  ChkIfA(0 != ::strncmp(c_username, (const char*)(spBuffer->GetData() + attrib.offset), attrib.size), E_FAIL);
100 
101 
102  ChkA(reader.GetStringAttributeByType(STUN_ATTRIBUTE_SOFTWARE, szStringValue, ARRAYSIZE(szStringValue)));
103  ChkIfA(0 != ::strcmp(c_software, szStringValue), E_FAIL);
104 
105  ChkIfA(reader.HasFingerprintAttribute() == false, E_FAIL);
106 
107  ChkIfA(reader.IsFingerprintAttributeValid() == false, E_FAIL);
108 
109  ChkIfA(reader.HasMessageIntegrityAttribute() == false, E_FAIL);
110 
112 
113 Cleanup:
114  return hr;
115  }
116 
118 {
119  HRESULT hr = S_OK;
120 
121  // this test is to validate an extreme case for TCP scenarios.
122  // what if the bytes only arrived "one at a time"?
123  // or if the byte chunks straddled across logical parse segments (i.e. the header and the body)
124  // Can CStunMessageReader::AddBytes handle and parse out the correct result
125 
126  for (size_t chunksize = 1; chunksize <= 30; chunksize++)
127  {
128  Chk(TestFixedReadSizes(chunksize));
129  }
130 
131  srand(888);
132  for (size_t i = 0; i < 200; i++)
133  {
135  }
136 Cleanup:
137  return hr;
138 }
139 
141 {
142 
143  HRESULT hr = S_OK;
144  CStunMessageReader reader;
145  CStunMessageReader::ReaderParseState prevState, state;
146  size_t bytesread = 0;
147  bool fRandomChunkSizing = (chunksize==0);
148 
149 
151  state = prevState;
152  size_t msgSize = sizeof(c_requestbytes)-1; // c_requestbytes is a string, hence the -1
153  while (bytesread < msgSize)
154  {
155  size_t remaining, toread;
156 
157  if (fRandomChunkSizing)
158  {
159  chunksize = (rand() % 17) + 1;
160  }
161 
162  remaining = msgSize - bytesread;
163  toread = (remaining > chunksize) ? chunksize : remaining;
164 
165  state = reader.AddBytes(&c_requestbytes[bytesread], toread);
166  bytesread += toread;
167 
169 
171  {
172  ChkIfA(bytesread < STUN_HEADER_SIZE, E_UNEXPECTED);
173  }
174 
176  {
178  ChkIfA(bytesread != msgSize, E_UNEXPECTED);
179  }
180 
181  prevState = state;
182  }
183 
185 
186  // just validate the integrity and fingerprint, that should cover all the attributes
188  ChkIfA(reader.IsFingerprintAttributeValid() == false, E_FAIL);
189 
190 Cleanup:
191  return hr;
192 }
193 
#define S_OK
Definition: hresult.h:46
const uint16_t STUN_ATTRIBUTE_USERNAME
Definition: stuntypes.h:39
uint16_t offset
Definition: stuntypes.h:112
HRESULT Test1()
Definition: testreader.cpp:60
const char c_password[]
Definition: testreader.cpp:45
uint16_t GetMessageType()
Definition: stunreader.cpp:839
HRESULT GetAttributeByType(uint16_t attributeType, StunAttribute *pAttribute)
Definition: stunreader.cpp:362
#define Chk(expr)
Definition: chkmacros.h:53
HRESULT GetBuffer(CRefCountedBuffer *pRefBuffer)
Definition: stunreader.cpp:844
bool HasFingerprintAttribute()
Definition: stunreader.cpp:93
#define ARRAYSIZE(arr)
const char c_username[]
Definition: testreader.cpp:46
ReaderParseState AddBytes(const uint8_t *pData, uint32_t size)
Definition: stunreader.cpp:750
#define E_UNEXPECTED
Definition: hresult.h:48
ReaderParseState GetState()
Definition: stunreader.cpp:820
uint16_t attributeType
Definition: stuntypes.h:110
HRESULT ValidateMessageIntegrityShort(const char *pszPassword)
Definition: stunreader.cpp:277
int32_t HRESULT
Definition: hresult.h:22
const uint16_t STUN_ATTRIBUTE_SOFTWARE
Definition: stuntypes.h:64
HRESULT Test2()
Definition: testreader.cpp:117
const unsigned char c_requestbytes[]
Definition: testreader.cpp:27
bool IsFingerprintAttributeValid()
Definition: stunreader.cpp:99
#define E_FAIL
Definition: hresult.h:56
StunMessageClass GetMessageClass()
Definition: stunreader.cpp:834
#define ChkA(expr)
Definition: chkmacros.h:73
bool HasMessageIntegrityAttribute()
Definition: stunreader.cpp:140
HRESULT TestFixedReadSizes(size_t chunksize)
Definition: testreader.cpp:140
boost::shared_ptr< CBuffer > CRefCountedBuffer
Definition: buffer.h:65
HRESULT GetStringAttributeByType(uint16_t attributeType, char *pszValue, size_t size)
Definition: stunreader.cpp:565
uint16_t HowManyBytesNeeded()
Definition: stunreader.cpp:76
HRESULT Run()
Definition: testreader.cpp:50
#define ChkIfA(expr, hrerror)
Definition: chkmacros.h:84
uint16_t size
Definition: stuntypes.h:111
const uint32_t STUN_HEADER_SIZE
Definition: stuntypes.h:176
const char c_software[]
Definition: testreader.cpp:47