Coverage Report

Created: 2025-06-13 06:12

/src/resiprocate/resip/stack/Via.cxx
Line
Count
Source (jump to first uncovered line)
1
#if defined(HAVE_CONFIG_H)
2
#include "config.h"
3
#endif
4
5
#include "resip/stack/Via.hxx"
6
#include "resip/stack/InteropHelper.hxx"
7
#include "rutil/DnsUtil.hxx"
8
#include "rutil/Logger.hxx"
9
#include "rutil/ParseBuffer.hxx"
10
//#include "rutil/WinLeakCheck.hxx"  // not compatible with placement new used below
11
12
using namespace resip;
13
using namespace std;
14
15
#define RESIPROCATE_SUBSYSTEM Subsystem::SIP
16
17
18
//====================
19
// Via:
20
//====================
21
Via::Via() 
22
0
   : ParserCategory(), 
23
0
     mProtocolName(Data::Share,Symbols::ProtocolName),
24
0
     mProtocolVersion(Data::Share,Symbols::ProtocolVersion),
25
0
     mTransport(),
26
0
     mSentHost(),
27
0
     mSentPort(0) 
28
0
{
29
   // insert a branch in all Vias (default constructor)
30
0
   this->param(p_branch);
31
0
   if(InteropHelper::getRportEnabled())
32
0
   {
33
0
      this->param(p_rport); // add the rport parameter by default as per rfc 3581
34
0
   }
35
0
}
36
37
Via::Via(const HeaderFieldValue& hfv, 
38
         Headers::Type type,
39
         PoolBase* pool) 
40
0
   : ParserCategory(hfv, type, pool),
41
0
     mProtocolName(Data::Share,Symbols::ProtocolName),
42
0
     mProtocolVersion(Data::Share,Symbols::ProtocolVersion),
43
0
     mTransport(Data::Share,Symbols::UDP), // !jf! 
44
0
     mSentHost(),
45
0
     mSentPort(-1) 
46
0
{}
47
48
Via::Via(const Via& rhs,
49
         PoolBase* pool)
50
0
   : ParserCategory(rhs, pool),
51
0
     mProtocolName(rhs.mProtocolName),
52
0
     mProtocolVersion(rhs.mProtocolVersion),
53
0
     mTransport(rhs.mTransport),
54
0
     mSentHost(rhs.mSentHost),
55
0
     mSentPort(rhs.mSentPort)
56
0
{
57
0
}
58
59
Via&
60
Via::operator=(const Via& rhs)
61
0
{
62
0
   if (this != &rhs)
63
0
   {
64
0
      ParserCategory::operator=(rhs);
65
0
      mProtocolName = rhs.mProtocolName;
66
0
      mProtocolVersion = rhs.mProtocolVersion;
67
0
      mTransport = rhs.mTransport;
68
0
      mSentHost = rhs.mSentHost;
69
0
      mSentPort = rhs.mSentPort;
70
0
   }
71
0
   return *this;
72
0
}
73
74
ParserCategory *
75
Via::clone() const
76
0
{
77
0
   return new Via(*this);
78
0
}
79
80
ParserCategory *
81
Via::clone(void* location) const
82
0
{
83
0
   return new (location) Via(*this);
84
0
}
85
86
ParserCategory* 
87
Via::clone(PoolBase* pool) const
88
0
{
89
0
   return new (pool) Via(*this, pool);
90
0
}
91
92
Data& 
93
Via::protocolName()
94
0
{
95
0
   checkParsed(); 
96
0
   return mProtocolName;
97
0
}
98
99
const Data& 
100
Via::protocolName() const 
101
0
{
102
0
   checkParsed(); 
103
0
   return mProtocolName;
104
0
}
105
106
Data& 
107
Via::protocolVersion()
108
0
{
109
0
   checkParsed(); 
110
0
   return mProtocolVersion;
111
0
}
112
113
const Data& 
114
Via::protocolVersion() const 
115
0
{
116
0
   checkParsed(); 
117
0
   return mProtocolVersion;
118
0
}
119
120
Data& Via::
121
transport()
122
0
{
123
0
   checkParsed(); 
124
0
   return mTransport;
125
0
}
126
127
const Data& Via::
128
transport() const 
129
0
{
130
0
   checkParsed(); 
131
0
   return mTransport;
132
0
}
133
134
Data& 
135
Via::sentHost()
136
0
{
137
0
   checkParsed(); 
138
0
   return mSentHost;
139
0
}
140
141
const Data&
142
 Via::sentHost() const
143
0
{
144
0
   checkParsed(); 
145
0
   return mSentHost;
146
0
}
147
148
int& 
149
Via::sentPort()
150
0
{
151
0
   checkParsed(); 
152
0
   return mSentPort;
153
0
}
154
155
int
156
Via::sentPort() const 
157
0
{
158
0
   checkParsed(); 
159
0
   return mSentPort;
160
0
}
161
162
void
163
Via::parse(ParseBuffer& pb)
164
0
{
165
0
   const char* startMark;
166
0
   startMark = pb.skipWhitespace();
167
0
   static std::bitset<256> wos=Data::toBitset("\r\n\t /");
168
0
   pb.skipToOneOf(wos);
169
0
   pb.data(mProtocolName, startMark);
170
0
   pb.skipToChar('/');
171
0
   pb.skipChar();
172
0
   startMark = pb.skipWhitespace();
173
0
   pb.skipToOneOf(wos);
174
0
   pb.data(mProtocolVersion, startMark);
175
176
0
   pb.skipToChar('/');
177
0
   pb.skipChar();
178
0
   startMark = pb.skipWhitespace();
179
180
   // !jf! this should really be skipTokenChar() since for instance, if the
181
   // protocol token is missing it will read the rest of the Via into this field
182
0
   pb.skipNonWhitespace(); 
183
0
   pb.data(mTransport, startMark);
184
   
185
0
   startMark = pb.skipWhitespace();
186
0
   pb.assertNotEof();
187
0
   if (*startMark == '[')
188
0
   {
189
0
      startMark = pb.skipChar();
190
0
      pb.skipToChar(']');
191
0
      pb.data(mSentHost, startMark);
192
      // .bwc. We do not save this canonicalization, since we weren't doing so
193
      // before. This may change soon.
194
0
      Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mSentHost);
195
0
      if(canonicalizedHost.empty())
196
0
      {
197
         // .bwc. So the V6 addy is garbage.
198
0
         throw ParseException("Unparsable V6 address (note, this might"
199
0
                                    " be unparsable because IPV6 support is not"
200
0
                                    " enabled)", "Via",
201
0
                                       __FILE__,
202
0
                                       __LINE__);
203
0
      }
204
0
      pb.skipChar();
205
0
   }
206
0
   else
207
0
   {
208
      // .bwc. If we hit whitespace, we have the host.
209
0
      static std::bitset<256> delimiter=Data::toBitset(";: \t\r\n");
210
0
      pb.skipToOneOf(delimiter);
211
0
      pb.data(mSentHost, startMark);
212
0
   }
213
214
0
   pb.skipToOneOf(";:");
215
   
216
0
   if (!pb.eof() && *pb.position() == ':')
217
0
   {
218
0
      startMark = pb.skipChar(':');
219
0
      mSentPort = pb.integer();
220
0
      static std::bitset<256> delimiter=Data::toBitset("; \t\r\n");
221
0
      pb.skipToOneOf(delimiter);
222
0
   }
223
0
   else
224
0
   {
225
0
      mSentPort = 0;
226
0
   }
227
0
   parseParameters(pb);
228
0
}
229
230
EncodeStream&
231
Via::encodeParsed(EncodeStream& str) const
232
0
{
233
0
   str << mProtocolName << Symbols::SLASH << mProtocolVersion << Symbols::SLASH << mTransport 
234
0
       << Symbols::SPACE;
235
236
0
   if (DnsUtil::isIpV6Address(mSentHost))
237
0
   {
238
0
      str << '[' << mSentHost << ']';
239
0
   }
240
0
   else
241
0
   {
242
0
      str << mSentHost;
243
0
   }
244
   
245
0
   if (mSentPort != 0)
246
0
   {
247
0
      str << Symbols::COLON << mSentPort;
248
0
   }
249
0
   encodeParameters(str);
250
0
   return str;
251
0
}
252
253
ParameterTypes::Factory Via::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0};
254
255
Parameter* 
256
Via::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool)
257
0
{
258
0
   if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type])
259
0
   {
260
0
      return ParameterFactories[type](type, pb, terminators, pool);
261
0
   }
262
0
   return 0;
263
0
}
264
265
bool 
266
Via::exists(const Param<Via>& paramType) const
267
0
{
268
0
    checkParsed();
269
0
    bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL;
270
0
    return ret;
271
0
}
272
273
void 
274
Via::remove(const Param<Via>& paramType)
275
0
{
276
0
    checkParsed();
277
0
    removeParameterByEnum(paramType.getTypeNum());
278
0
}
279
280
#define defineParam(_enum, _name, _type, _RFC_ref_ignored)                                                      \
281
_enum##_Param::DType&                                                                                           \
282
0
Via::param(const _enum##_Param& paramType)                                                           \
283
0
{                                                                                                               \
284
0
   checkParsed();                                                                                               \
285
0
   _enum##_Param::Type* p =                                                                                     \
286
0
      static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
287
0
   if (!p)                                                                                                      \
288
0
   {                                                                                                            \
289
0
      p = new _enum##_Param::Type(paramType.getTypeNum());                                                      \
290
0
      mParameters.push_back(p);                                                                                 \
291
0
   }                                                                                                            \
292
0
   return p->value();                                                                                           \
293
0
}                                                                                                               \
Unexecuted instantiation: resip::Via::param(resip::branch_Param const&)
Unexecuted instantiation: resip::Via::param(resip::comp_Param const&)
Unexecuted instantiation: resip::Via::param(resip::received_Param const&)
Unexecuted instantiation: resip::Via::param(resip::rport_Param const&)
Unexecuted instantiation: resip::Via::param(resip::ttl_Param const&)
Unexecuted instantiation: resip::Via::param(resip::sigcompId_Param const&)
Unexecuted instantiation: resip::Via::param(resip::maddr_Param const&)
294
                                                                                                                \
295
const _enum##_Param::DType&                                                                                     \
296
0
Via::param(const _enum##_Param& paramType) const                                                     \
297
0
{                                                                                                               \
298
0
   checkParsed();                                                                                               \
299
0
   _enum##_Param::Type* p =                                                                                     \
300
0
      static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
301
0
   if (!p)                                                                                                      \
302
0
   {                                                                                                            \
303
0
      InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]);     \
304
0
      DebugLog(<< *this);                                                                                       \
305
0
      throw Exception("Missing parameter " _name, __FILE__, __LINE__);                                          \
306
0
   }                                                                                                            \
307
0
   return p->value();                                                                                           \
308
0
}
Unexecuted instantiation: resip::Via::param(resip::branch_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::comp_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::received_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::rport_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::ttl_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::sigcompId_Param const&) const
Unexecuted instantiation: resip::Via::param(resip::maddr_Param const&) const
309
310
defineParam(branch, "branch", BranchParameter, "RFC 3261");
311
defineParam(comp, "comp", DataParameter, "RFC 3486");
312
defineParam(received, "received", ReceivedParameter, "RFC 3261");
313
defineParam(rport, "rport", RportParameter, "RFC 3581");
314
defineParam(ttl, "ttl", UInt32Parameter, "RFC 3261");
315
defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049");
316
defineParam(maddr, "maddr", DataParameter, "RFC 3261");
317
318
#undef defineParam
319
320
/* ====================================================================
321
 * The Vovida Software License, Version 1.0 
322
 * 
323
 * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
324
 * 
325
 * Redistribution and use in source and binary forms, with or without
326
 * modification, are permitted provided that the following conditions
327
 * are met:
328
 * 
329
 * 1. Redistributions of source code must retain the above copyright
330
 *    notice, this list of conditions and the following disclaimer.
331
 * 
332
 * 2. Redistributions in binary form must reproduce the above copyright
333
 *    notice, this list of conditions and the following disclaimer in
334
 *    the documentation and/or other materials provided with the
335
 *    distribution.
336
 * 
337
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
338
 *    and "Vovida Open Communication Application Library (VOCAL)" must
339
 *    not be used to endorse or promote products derived from this
340
 *    software without prior written permission. For written
341
 *    permission, please contact vocal@vovida.org.
342
 *
343
 * 4. Products derived from this software may not be called "VOCAL", nor
344
 *    may "VOCAL" appear in their name, without prior written
345
 *    permission of Vovida Networks, Inc.
346
 * 
347
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
348
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
349
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
350
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
351
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
352
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
353
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
354
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
355
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
356
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
357
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
358
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
359
 * DAMAGE.
360
 * 
361
 * ====================================================================
362
 * 
363
 * This software consists of voluntary contributions made by Vovida
364
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
365
 * Inc.  For more information on Vovida Networks, Inc., please see
366
 * <http://www.vovida.org/>.
367
 *
368
 */