/[resiprocate]/branches/b-identity-0505/InternalTransport.cxx
ViewVC logotype

Contents of /branches/b-identity-0505/InternalTransport.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4598 - (show annotations) (download)
Wed May 11 22:53:07 2005 UTC (14 years, 6 months ago) by derek
File size: 7719 byte(s)
set svn:eol-style to LF
1 #if defined(HAVE_CONFIG_H)
2 #include "resiprocate/config.hxx"
3 #endif
4
5 #include <iostream>
6
7 #if defined(HAVE_SYS_SOCKIO_H)
8 #include <sys/sockio.h>
9 #endif
10
11 #include "resiprocate/Helper.hxx"
12 #include "resiprocate/InternalTransport.hxx"
13 #include "resiprocate/SipMessage.hxx"
14 #include "resiprocate/TransportMessage.hxx"
15 #include "resiprocate/os/DnsUtil.hxx"
16 #include "resiprocate/os/Logger.hxx"
17 #include "resiprocate/os/Socket.hxx"
18 #include "resiprocate/os/compat.hxx"
19 #include "resiprocate/os/WinLeakCheck.hxx"
20
21 using namespace resip;
22 using namespace std;
23
24 #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT
25
26
27 InternalTransport::InternalTransport(Fifo<TransactionMessage>& rxFifo,
28 int portNum,
29 IpVersion version,
30 const Data& interfaceObj) :
31 Transport(rxFifo, portNum, version, interfaceObj),
32 mFd(-1),
33 mHasOwnThread(false)
34 {
35 }
36
37 InternalTransport::~InternalTransport()
38 {
39 if (mFd != -1)
40 {
41 //DebugLog (<< "Closing " << mFd);
42 closeSocket(mFd);
43 }
44 mFd = -2;
45 }
46
47 bool
48 InternalTransport::isFinished() const
49 {
50 return !mTxFifo.messageAvailable();
51 }
52
53 Socket
54 InternalTransport::socket(TransportType type, IpVersion ipVer)
55 {
56 Socket fd;
57 switch (type)
58 {
59 case UDP:
60 #ifdef USE_IPV6
61 fd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
62 #else
63 fd = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
64 #endif
65 break;
66 case TCP:
67 case TLS:
68 #ifdef USE_IPV6
69 fd = ::socket(ipVer == V4 ? PF_INET : PF_INET6, SOCK_STREAM, 0);
70 #else
71 fd = ::socket(PF_INET, SOCK_STREAM, 0);
72 #endif
73 break;
74 default:
75 InfoLog (<< "Try to create an unsupported socket type: " << Tuple::toData(type));
76 assert(0);
77 throw Transport::Exception("Unsupported transport", __FILE__,__LINE__);
78 }
79
80 if ( fd == INVALID_SOCKET )
81 {
82 int e = getErrno();
83 InfoLog (<< "Failed to create socket: " << strerror(e));
84 throw Transport::Exception("Can't create TcpBaseTransport", __FILE__,__LINE__);
85 }
86
87 DebugLog (<< "Creating fd=" << fd << (ipVer == V4 ? " V4/" : " V6/") << (type == UDP ? "UDP" : "TCP"));
88
89 return fd;
90 }
91
92 void
93 InternalTransport::bind()
94 {
95 DebugLog (<< "Binding to " << DnsUtil::inet_ntop(mTuple));
96
97 if ( ::bind( mFd, &mTuple.getMutableSockaddr(), mTuple.length()) == SOCKET_ERROR )
98 {
99 int e = getErrno();
100 if ( e == EADDRINUSE )
101 {
102 error(e);
103 ErrLog (<< mTuple << " already in use ");
104 throw Transport::Exception("port already in use", __FILE__,__LINE__);
105 }
106 else
107 {
108 error(e);
109 ErrLog (<< "Could not bind to " << mTuple);
110 throw Transport::Exception("Could not use port", __FILE__,__LINE__);
111 }
112 }
113
114 bool ok = makeSocketNonBlocking(mFd);
115 if ( !ok )
116 {
117 ErrLog (<< "Could not make socket non-blocking " << port());
118 throw Transport::Exception("Failed making socket non-blocking", __FILE__,__LINE__);
119 }
120 }
121
122 unsigned int
123 InternalTransport::getFifoSize() const
124 {
125 return mTxFifo.size();
126 }
127
128 void
129 InternalTransport::thread()
130 {
131 InfoLog (<< "Starting transport thread for " << mTuple);
132 #if defined(USE_EPOLL)
133 int epollfd = ::open("/dev/epoll", O_RDWR);
134 if (epollfd < 0)
135 {
136 int e = getErrno();
137 Transport::error( e );
138 ErrLog (<< "Can't find epoll on this system");
139 assert(0);
140 }
141
142 int ret = ::ioctl(epollfd, EP_ALLOC, maxFileDescriptors());
143 if (ret != 0)
144 {
145 int e = getErrno();
146 Transport::error( e );
147 ErrLog (<< "Failed to define for " << maxFileDescriptors() << " descriptors");
148 assert(0);
149 }
150
151 char *map = (char *)mmap(NULL, EP_MAP_SIZE(maxFileDescriptors(),
152 PROT_READ | PROT_WRITE, MAP_PRIVATE, n
153 epollfd, 0));
154 if (map <= 0)
155 {
156 ErrLog (<< "Failed to allocate space for epoll in kernel for " << maxFileDescriptors() << " descriptors");
157 assert(0);
158 }
159
160 while (!mShutdown)
161 {
162 struct pollfd pfd;
163 pfd.fd = fd;
164 pfd.events = POLLIN | POLLOUT | POLLERR | POLLHUP;
165 pfd.revents = 0;
166
167 if (write(kdpfd, &pfd, sizeof(pfd)) != sizeof(pfd))
168 {
169
170 /* report error */
171 }
172
173
174
175
176 FdSet fdset;
177 buildFdSet(fdset);
178 int err = fdset.selectMilliSeconds(100);
179 if (err >= 0)
180 {
181 try
182 {
183 process(fdset);
184 }
185 catch (BaseException& e)
186 {
187 InfoLog (<< "Uncaught exception: " << e);
188 }
189 }
190 }
191 #else // !USE_EPOLL
192 while (!mShutdown)
193 {
194 FdSet fdset;
195 buildFdSet(fdset);
196 int err = fdset.selectMilliSeconds(100);
197 if (err >= 0)
198 {
199 try
200 {
201 process(fdset);
202 }
203 catch (BaseException& e)
204 {
205 InfoLog (<< "Uncaught exception: " << e);
206 }
207 }
208 }
209 #endif
210 InfoLog (<< "shutdown: ");
211 }
212
213 bool
214 InternalTransport::hasDataToSend() const
215 {
216 return mTxFifo.messageAvailable();
217 }
218
219 void
220 InternalTransport::transmit(const Tuple& dest, const Data& pdata, const Data& tid)
221 {
222 SendData* data = new SendData(dest, pdata, tid);
223 mTxFifo.add(data);
224 }
225
226 /* ====================================================================
227 * The Vovida Software License, Version 1.0
228 *
229 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
230 *
231 * Redistribution and use in source and binary forms, with or without
232 * modification, are permitted provided that the following conditions
233 * are met:
234 *
235 * 1. Redistributions of source code must retain the above copyright
236 * notice, this list of conditions and the following disclaimer.
237 *
238 * 2. Redistributions in binary form must reproduce the above copyright
239 * notice, this list of conditions and the following disclaimer in
240 * the documentation and/or other materials provided with the
241 * distribution.
242 *
243 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
244 * and "Vovida Open Communication Application Library (VOCAL)" must
245 * not be used to endorse or promote products derived from this
246 * software without prior written permission. For written
247 * permission, please contact vocal@vovida.org.
248 *
249 * 4. Products derived from this software may not be called "VOCAL", nor
250 * may "VOCAL" appear in their name, without prior written
251 * permission of Vovida Networks, Inc.
252 *
253 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
254 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
255 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
256 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
257 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
258 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
259 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
260 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
261 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
262 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
263 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
264 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
265 * DAMAGE.
266 *
267 * ====================================================================
268 *
269 * This software consists of voluntary contributions made by Vovida
270 * Networks, Inc. and many individuals on behalf of Vovida Networks,
271 * Inc. For more information on Vovida Networks, Inc., please see
272 * <http://www.vovida.org/>.
273 *
274 */

Properties

Name Value
svn:eol-style LF
svn:executable *

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27