Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
asterisk
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Voice
asterisk
Commits
762f40fc
Commit
762f40fc
authored
6 years ago
by
Friendly Automation
Committed by
Gerrit Code Review
6 years ago
Browse files
Options
Downloads
Plain Diff
Merge "res/res_pjsip: Fix crash due to misuse of session->media between threads." into 13
parents
a1d7d469
c01d2f66
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
res/res_pjsip_t38.c
+51
-12
51 additions, 12 deletions
res/res_pjsip_t38.c
with
51 additions
and
12 deletions
res/res_pjsip_t38.c
+
51
−
12
View file @
762f40fc
...
@@ -79,6 +79,17 @@ static const struct ast_datastore_info t38_datastore = {
...
@@ -79,6 +79,17 @@ static const struct ast_datastore_info t38_datastore = {
.
destroy
=
t38_state_destroy
,
.
destroy
=
t38_state_destroy
,
};
};
static
void
session_media_dec
(
void
*
obj
)
{
ao2_cleanup
(
obj
);
}
/*! \brief Datastore for T.38 session_media information */
static
const
struct
ast_datastore_info
session_media_datastore
=
{
.
type
=
"t38_session_media"
,
.
destroy
=
session_media_dec
,
};
/*! \brief Structure for T.38 parameters task data */
/*! \brief Structure for T.38 parameters task data */
struct
t38_parameters_task_data
{
struct
t38_parameters_task_data
{
/*! \brief Session itself */
/*! \brief Session itself */
...
@@ -120,6 +131,36 @@ static struct t38_parameters_task_data *t38_parameters_task_data_alloc(struct as
...
@@ -120,6 +131,36 @@ static struct t38_parameters_task_data *t38_parameters_task_data_alloc(struct as
return
data
;
return
data
;
}
}
/*! \brief Helper function which retrieves a T.38 session_media from datastore */
static
struct
ast_sip_session_media
*
session_media_from_datastore_addref
(
struct
ast_sip_session
*
session
)
{
struct
ast_datastore
*
datastore
=
NULL
;
struct
ast_sip_session_media
*
session_media
=
NULL
;
if
((
datastore
=
ast_sip_session_get_datastore
(
session
,
"t38_session_media"
)))
{
session_media
=
datastore
->
data
;
ao2_ref
(
session_media
,
+
1
);
ao2_ref
(
datastore
,
-
1
);
}
return
session_media
;
}
/*! \brief Helper function which allocates datastore with a session media */
static
struct
ast_datastore
*
create_datastore_session_media
(
struct
ast_sip_session
*
session
,
struct
ast_sip_session_media
*
session_media
)
{
struct
ast_datastore
*
datastore
=
NULL
;
if
(
!
(
datastore
=
ast_sip_session_alloc_datastore
(
&
session_media_datastore
,
"t38_session_media"
))
||
ast_sip_session_add_datastore
(
session
,
datastore
))
{
return
NULL
;
}
datastore
->
data
=
session_media
;
ao2_bump
(
session_media
);
return
datastore
;
}
/*! \brief Helper function for changing the T.38 state */
/*! \brief Helper function for changing the T.38 state */
static
void
t38_change_state
(
struct
ast_sip_session
*
session
,
struct
ast_sip_session_media
*
session_media
,
static
void
t38_change_state
(
struct
ast_sip_session
*
session
,
struct
ast_sip_session_media
*
session_media
,
struct
t38_state
*
state
,
enum
ast_sip_session_t38state
new_state
)
struct
t38_state
*
state
,
enum
ast_sip_session_t38state
new_state
)
...
@@ -198,7 +239,7 @@ static int t38_automatic_reject(void *obj)
...
@@ -198,7 +239,7 @@ static int t38_automatic_reject(void *obj)
{
{
RAII_VAR
(
struct
ast_sip_session
*
,
session
,
obj
,
ao2_cleanup
);
RAII_VAR
(
struct
ast_sip_session
*
,
session
,
obj
,
ao2_cleanup
);
RAII_VAR
(
struct
ast_datastore
*
,
datastore
,
ast_sip_session_get_datastore
(
session
,
"t38"
),
ao2_cleanup
);
RAII_VAR
(
struct
ast_datastore
*
,
datastore
,
ast_sip_session_get_datastore
(
session
,
"t38"
),
ao2_cleanup
);
RAII_VAR
(
struct
ast_sip_session_media
*
,
session_media
,
ao2_find
(
session
->
media
,
"image"
,
OBJ_KEY
),
ao2_cleanup
);
RAII_VAR
(
struct
ast_sip_session_media
*
,
session_media
,
session
_
media
_from_datastore_addref
(
session
),
ao2_cleanup
);
if
(
!
datastore
)
{
if
(
!
datastore
)
{
return
0
;
return
0
;
...
@@ -255,6 +296,10 @@ static int t38_initialize_session(struct ast_sip_session *session, struct ast_si
...
@@ -255,6 +296,10 @@ static int t38_initialize_session(struct ast_sip_session *session, struct ast_si
return
0
;
return
0
;
}
}
if
(
!
create_datastore_session_media
(
session
,
session_media
))
{
return
-
1
;
}
if
(
!
(
session_media
->
udptl
=
ast_udptl_new_with_bindaddr
(
NULL
,
NULL
,
0
,
&
address
)))
{
if
(
!
(
session_media
->
udptl
=
ast_udptl_new_with_bindaddr
(
NULL
,
NULL
,
0
,
&
address
)))
{
return
-
1
;
return
-
1
;
}
}
...
@@ -292,7 +337,8 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
...
@@ -292,7 +337,8 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
{
{
struct
pjsip_status_line
status
=
rdata
->
msg_info
.
msg
->
line
.
status
;
struct
pjsip_status_line
status
=
rdata
->
msg_info
.
msg
->
line
.
status
;
struct
t38_state
*
state
;
struct
t38_state
*
state
;
struct
ast_sip_session_media
*
session_media
=
NULL
;
RAII_VAR
(
struct
ast_sip_session_media
*
,
session_media
,
session_media_from_datastore_addref
(
session
),
ao2_cleanup
);
if
(
status
.
code
/
100
<=
1
)
{
if
(
status
.
code
/
100
<=
1
)
{
/* Ignore any non-final responses (1xx) */
/* Ignore any non-final responses (1xx) */
...
@@ -300,7 +346,7 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
...
@@ -300,7 +346,7 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
}
}
if
(
!
session
->
channel
||
!
(
state
=
t38_state_get_or_alloc
(
session
))
||
if
(
!
session
->
channel
||
!
(
state
=
t38_state_get_or_alloc
(
session
))
||
!
(
session_media
=
ao2_find
(
session
->
media
,
"image"
,
OBJ_KEY
))
)
{
!
session_media
)
{
ast_log
(
LOG_WARNING
,
"Received %d response to T.38 re-invite on '%s' but state unavailable
\n
"
,
ast_log
(
LOG_WARNING
,
"Received %d response to T.38 re-invite on '%s' but state unavailable
\n
"
,
status
.
code
,
status
.
code
,
session
->
channel
?
ast_channel_name
(
session
->
channel
)
:
"unknown channel"
);
session
->
channel
?
ast_channel_name
(
session
->
channel
)
:
"unknown channel"
);
...
@@ -311,7 +357,6 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
...
@@ -311,7 +357,6 @@ static int t38_reinvite_response_cb(struct ast_sip_session *session, pjsip_rx_da
t38_change_state
(
session
,
session_media
,
state
,
t38_change_state
(
session
,
session_media
,
state
,
(
status
.
code
/
100
==
2
)
?
T38_ENABLED
:
T38_REJECTED
);
(
status
.
code
/
100
==
2
)
?
T38_ENABLED
:
T38_REJECTED
);
ao2_cleanup
(
session_media
);
return
0
;
return
0
;
}
}
...
@@ -446,10 +491,7 @@ static struct ast_frame *t38_framehook_write(struct ast_channel *chan,
...
@@ -446,10 +491,7 @@ static struct ast_frame *t38_framehook_write(struct ast_channel *chan,
}
else
if
(
f
->
frametype
==
AST_FRAME_MODEM
)
{
}
else
if
(
f
->
frametype
==
AST_FRAME_MODEM
)
{
struct
ast_sip_session_media
*
session_media
;
struct
ast_sip_session_media
*
session_media
;
/* Avoid deadlock between chan and the session->media container lock */
session_media
=
session_media_from_datastore_addref
(
session
);
ast_channel_unlock
(
chan
);
session_media
=
ao2_find
(
session
->
media
,
"image"
,
OBJ_SEARCH_KEY
);
ast_channel_lock
(
chan
);
if
(
session_media
&&
session_media
->
udptl
)
{
if
(
session_media
&&
session_media
->
udptl
)
{
ast_udptl_write
(
session_media
->
udptl
,
f
);
ast_udptl_write
(
session_media
->
udptl
,
f
);
}
}
...
@@ -466,10 +508,7 @@ static struct ast_frame *t38_framehook_read(struct ast_channel *chan,
...
@@ -466,10 +508,7 @@ static struct ast_frame *t38_framehook_read(struct ast_channel *chan,
if
(
ast_channel_fdno
(
session
->
channel
)
==
5
)
{
if
(
ast_channel_fdno
(
session
->
channel
)
==
5
)
{
struct
ast_sip_session_media
*
session_media
;
struct
ast_sip_session_media
*
session_media
;
/* Avoid deadlock between chan and the session->media container lock */
session_media
=
session_media_from_datastore_addref
(
session
);
ast_channel_unlock
(
chan
);
session_media
=
ao2_find
(
session
->
media
,
"image"
,
OBJ_SEARCH_KEY
);
ast_channel_lock
(
chan
);
if
(
session_media
&&
session_media
->
udptl
)
{
if
(
session_media
&&
session_media
->
udptl
)
{
f
=
ast_udptl_read
(
session_media
->
udptl
);
f
=
ast_udptl_read
(
session_media
->
udptl
);
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment