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') |
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 | ||||
61 | struct registrar_usage | |||
62 | { | |||
63 | tport_t *tport; /**< */ | |||
64 | int pending; /**< Waiting for tport to close */ | |||
65 | }; | |||
66 | ||||
67 | static char const *nua_registrar_usage_name(nua_dialog_usage_t const *du) | |||
68 | { | |||
69 | return "registrar"; | |||
70 | } | |||
71 | ||||
72 | static 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 | ||||
79 | static 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)); | |||
| ||||
88 | ||||
89 | if (ru->pending) | |||
| ||||
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 | ||||
95 | static 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 | */ | |||
108 | static 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 | ||||
115 | static 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 | ||||
172 | static int nua_registrar_server_preprocess(nua_server_request_t *sr); | |||
173 | static int nua_registrar_server_report(nua_server_request_t *, tagi_t const *); | |||
174 | ||||
175 | nua_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 | ||||
192 | static void | |||
193 | registrar_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 | ||||
218 | static int | |||
219 | nua_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 | ||||
258 | static int | |||
259 | nua_registrar_server_report(nua_server_request_t *sr, tagi_t const *tags) | |||
260 | { | |||
261 | return nua_base_server_report(sr, tags); | |||
262 | } |