Bug Summary

File:libs/sofia-sip/libsofia-sip-ua/nua/nua_registrar.c
Location:line 89, column 7
Description:Access to field 'pending' results in a dereference of a null pointer (loaded from variable 'ru')

Annotated Source Code

1/*
2 * This file is part of the Sofia-SIP package
3 *
4 * Copyright (C) 2006 Nokia Corporation.
5 *
6 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25/**@CFILE nua_registrar.c
26 * @brief REGISTER UAS
27 *
28 * @author Michael Jerris
29 *
30 * @date Created: Tue Oct 3 10:14:54 EEST 2006 ppessi
31 */
32
33#include "config.h"
34
35#include <stddef.h>
36#include <stdlib.h>
37#include <string.h>
38#include <limits.h>
39
40#include <assert.h>
41
42#define TP_CLIENT_Tstruct nua_handle_s struct nua_handle_s
43#define TP_STACK_Tstruct nta_agent_s struct nta_agent_s
44
45#include <sofia-sip/su_string.h>
46#include <sofia-sip/sip_protos.h>
47#include <sofia-sip/sip_status.h>
48#include <sofia-sip/sip_util.h>
49
50#define NTA_INCOMING_MAGIC_Tstruct nua_handle_s struct nua_handle_s
51#define NTA_RELIABLE_MAGIC_Tstruct nua_handle_s struct nua_handle_s
52
53#include "nua_stack.h"
54
55#include <sofia-sip/tport.h>
56#include <sofia-sip/nta_tport.h>
57
58/* ---------------------------------------------------------------------- */
59/* Registrar usage */
60
61struct registrar_usage
62{
63 tport_t *tport; /**< */
64 int pending; /**< Waiting for tport to close */
65};
66
67static char const *nua_registrar_usage_name(nua_dialog_usage_t const *du)
68{
69 return "registrar";
70}
71
72static int nua_registrar_usage_add(nua_handle_t *nh,
73 nua_dialog_state_t *ds,
74 nua_dialog_usage_t *du)
75{
76 return 0;
77}
78
79static void nua_registrar_usage_remove(nua_handle_t *nh,
80 nua_dialog_state_t *ds,
81 nua_dialog_usage_t *du,
82 nua_client_request_t *cr,
83 nua_server_request_t *sr)
84{
85 struct registrar_usage *ru;
86
87 ru = nua_dialog_usage_private(du)((du) ? (void*)((du) + 1) : ((void*)0));
1
Null pointer value stored to 'ru'
88
89 if (ru->pending)
2
Access to field 'pending' results in a dereference of a null pointer (loaded from variable 'ru')
90 tport_release(ru->tport, ru->pending, NULL((void*)0), NULL((void*)0), nh, 0), ru->pending = 0;
91
92 tport_unref(ru->tport), ru->tport = NULL((void*)0);
93}
94
95static void nua_registrar_usage_refresh(nua_handle_t *nh,
96 nua_dialog_state_t *ds,
97 nua_dialog_usage_t *du,
98 sip_time_t now)
99{
100}
101
102/** Terminate registration usage.
103 *
104 * @retval >0 shutdown done
105 * @retval 0 shutdown in progress
106 * @retval <0 try again later
107 */
108static int nua_registrar_usage_shutdown(nua_handle_t *nh,
109 nua_dialog_state_t *ds,
110 nua_dialog_usage_t *du)
111{
112 return 1;
113}
114
115static nua_usage_class const nua_registrar_usage[1] = {
116 {
117 sizeof (struct registrar_usage), sizeof nua_registrar_usage,
118 nua_registrar_usage_add,
119 nua_registrar_usage_remove,
120 nua_registrar_usage_name,
121 nua_base_usage_update_params,
122 NULL((void*)0),
123 nua_registrar_usage_refresh,
124 nua_registrar_usage_shutdown
125 }};
126
127
128/* ======================================================================== */
129/* REGISTER */
130
131/** @NUA_EVENT nua_i_register
132 *
133 * Incoming REGISTER request.
134 *
135 * In order to receive #nua_i_register events, the application must enable
136 * the REGISTER method with NUTAG_ALLOW() tag, e.g.,
137 * @verbatim
138 * nua_set_params(nua;
139 * NUTAG_APPL_METHOD("REGISTER"),
140 * NUTAG_ALLOW("REGISTER"),
141 * TAG_END());
142 * @endverbatim
143 *
144 * The nua_response() call responding to a REGISTER request must include
145 * NUTAG_WITH() (or NUTAG_WITH_THIS()/NUTAG_WITH_SAVED()) tag. Note that
146 * a successful response to REGISTER @b MUST include the @Contact header
147 * bound to the the AoR URI (in @To header).
148 *
149 * The REGISTER request does not create a dialog. Currently the processing
150 * of incoming REGISTER creates a new handle for each incoming request which
151 * is not assiciated with an existing dialog. If the handle @a nh is not
152 * bound, you should probably destroy it after responding to the REGISTER
153 * request.
154 *
155 * @param status status code of response sent automatically by stack
156 * @param phrase a short textual description of @a status code
157 * @param nh operation handle associated with the request
158 * @param hmagic application context associated with the handle
159 * (usually NULL)
160 * @param sip incoming REGISTER request
161 * @param tags empty
162 *
163 * @sa nua_respond(), @RFC3261 section 10.3,
164 * @Expires, @Contact, @CallID, @CSeq,
165 * @Path, @RFC3327, @ServiceRoute, @RFC3608, @RFC3680,
166 * nua_register(), #nua_i_register, nua_unregister(), #nua_i_unregister
167 *
168 * @since New in @VERSION_1_12_4
169 * @END_NUA_EVENT
170 */
171
172static int nua_registrar_server_preprocess(nua_server_request_t *sr);
173static int nua_registrar_server_report(nua_server_request_t *, tagi_t const *);
174
175nua_server_methods_t const nua_register_server_methods =
176 {
177 SIP_METHOD_REGISTERsip_method_register, "REGISTER",
178 nua_i_register, /* Event */
179 {
180 0, /* Do not create dialog */
181 0, /* Initial request */
182 0, /* Not a target refresh request */
183 0, /* Do not add Contact */
184 },
185 nua_base_server_init((void*)0),
186 nua_registrar_server_preprocess,
187 nua_base_server_params((void*)0),
188 nua_base_server_respond,
189 nua_registrar_server_report,
190 };
191
192static void
193registrar_tport_error(nta_agent_t *nta, nua_handle_t *nh,
194 tport_t *tp, msg_t *msg, int error)
195{
196 nua_dialog_state_t *ds = nh->nh_ds;
197 nua_dialog_usage_t *du;
198 struct registrar_usage *ru;
199
200 SU_DEBUG_3(("tport error %d: %s\n", error, su_strerror(error)))((((nua_log) != ((void*)0) && (nua_log)->log_init)
== 0 ? 9 : (((nua_log) != ((void*)0) && (nua_log)->
log_init > 1) ? (nua_log)->log_level : su_log_default->
log_level)) >= 3 ? (_su_llog((nua_log), 3, "nua_registrar.c"
, (const char *)__func__, 200, "tport error %d: %s\n", error,
su_strerror(error))) : (void)0)
;
201
202 du = nua_dialog_usage_get(ds, nua_registrar_usage, NULL((void*)0));
203
204 if (du == NULL((void*)0))
205 return;
206
207 ru = nua_dialog_usage_private(du)((du) ? (void*)((du) + 1) : ((void*)0));
208 if (ru->tport) {
209 tport_release(ru->tport, ru->pending, NULL((void*)0), NULL((void*)0), nh, 0), ru->pending = 0;
210 tport_unref(ru->tport), ru->tport = NULL((void*)0);
211 }
212
213 nua_stack_event(nh->nh_nua, nh, NULL((void*)0),
214 nua_i_media_error, 500, "Transport error detected",
215 NULL((void*)0));
216}
217
218static int
219nua_registrar_server_preprocess(nua_server_request_t *sr)
220{
221 nua_handle_t *nh = sr->sr_owner;
222 nua_dialog_state_t *ds = sr->sr_owner->nh_ds;
223 nua_dialog_usage_t *du;
224 struct registrar_usage *ru;
225 tport_t *tport;
226
227 tport = nta_incoming_transport(nh->nh_nua->nua_nta, sr->sr_irq, sr->sr_request.msg);
228
229 if (!tport_is_tcp(tport)) {
230 tport_unref(tport);
231 return 0;
232 }
233
234 du = nua_dialog_usage_get(ds, nua_registrar_usage, NULL((void*)0));
235 if (du == NULL((void*)0))
236 du = nua_dialog_usage_add(nh, ds, nua_registrar_usage, NULL((void*)0));
237
238 if (du == NULL((void*)0))
239 return SR_STATUS1(sr, SIP_500_INTERNAL_SERVER_ERROR)sr_status(sr, 500, sip_500_Internal_server_error);
240
241 ru = nua_dialog_usage_private(du)((du) ? (void*)((du) + 1) : ((void*)0));
242
243 if (ru->tport && ru->tport != tport) {
244 tport_release(ru->tport, ru->pending, NULL((void*)0), NULL((void*)0), nh, 0), ru->pending = 0;
245 tport_unref(ru->tport), ru->tport = NULL((void*)0);
246 }
247
248 ru->tport = tport;
249 ru->pending = tport_pend(tport, NULL((void*)0), registrar_tport_error, nh);
250
251 tport_set_params(tport,
252 TPTAG_SDWN_ERROR(1)tptag_sdwn_error, tag_bool_v((1)),
253 TAG_END()(tag_type_t)0, (tag_value_t)0);
254
255 return 0;
256}
257
258static int
259nua_registrar_server_report(nua_server_request_t *sr, tagi_t const *tags)
260{
261 return nua_base_server_report(sr, tags);
262}