Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d7b59481
Commit
d7b59481
authored
Oct 13, 2002
by
Sridhar Samudrala
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
c6b7c070
ef012690
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
18 deletions
+96
-18
include/net/sctp/structs.h
include/net/sctp/structs.h
+3
-0
net/sctp/input.c
net/sctp/input.c
+35
-5
net/sctp/socket.c
net/sctp/socket.c
+58
-13
No files found.
include/net/sctp/structs.h
View file @
d7b59481
...
...
@@ -1044,6 +1044,9 @@ sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep,
sctp_endpoint_t
*
sctp_endpoint_is_match
(
sctp_endpoint_t
*
,
const
sockaddr_storage_t
*
);
int
sctp_has_association
(
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
paddr
);
int
sctp_verify_init
(
const
sctp_association_t
*
asoc
,
sctp_cid_t
cid
,
sctp_init_chunk_t
*
peer_init
,
...
...
net/sctp/input.c
View file @
d7b59481
...
...
@@ -522,7 +522,7 @@ void __sctp_unhash_established(sctp_association_t *asoc)
}
/* Look up an association. */
sctp_association_t
*
__sctp_
rcv_
lookup_association
(
const
sockaddr_storage_t
*
laddr
,
sctp_association_t
*
__sctp_lookup_association
(
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transportp
)
{
...
...
@@ -557,6 +557,36 @@ sctp_association_t *__sctp_rcv_lookup_association(const sockaddr_storage_t *ladd
return
asoc
;
}
/* Look up an association. BH-safe. */
sctp_association_t
*
sctp_lookup_association
(
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
paddr
,
sctp_transport_t
**
transportp
)
{
sctp_association_t
*
asoc
;
sctp_local_bh_disable
();
asoc
=
__sctp_lookup_association
(
laddr
,
paddr
,
transportp
);
sctp_local_bh_enable
();
return
asoc
;
}
/* Is there an association matching the given local and peer addresses? */
int
sctp_has_association
(
const
sockaddr_storage_t
*
laddr
,
const
sockaddr_storage_t
*
paddr
)
{
sctp_association_t
*
asoc
;
sctp_transport_t
*
transport
;
if
(
asoc
=
sctp_lookup_association
(
laddr
,
paddr
,
&
transport
))
{
sock_put
(
asoc
->
base
.
sk
);
sctp_association_put
(
asoc
);
return
1
;
}
return
0
;
}
/*
* SCTP Implementors Guide, 2.18 Handling of address
* parameters within the INIT or INIT-ACK.
...
...
@@ -633,7 +663,7 @@ static sctp_association_t *__sctp_rcv_initack_lookup(struct sk_buff *skb,
sctp_param2sockaddr
(
paddr
,
(
sctp_addr_param_t
*
)
parm
,
ntohs
(
sh
->
source
));
asoc
=
__sctp_
rcv_
lookup_association
(
laddr
,
paddr
,
transportp
);
asoc
=
__sctp_lookup_association
(
laddr
,
paddr
,
transportp
);
if
(
asoc
)
return
asoc
;
}
...
...
@@ -649,7 +679,7 @@ sctp_association_t *__sctp_rcv_lookup(struct sk_buff *skb,
{
sctp_association_t
*
asoc
;
asoc
=
__sctp_
rcv_
lookup_association
(
laddr
,
paddr
,
transportp
);
asoc
=
__sctp_lookup_association
(
laddr
,
paddr
,
transportp
);
/* Further lookup for INIT-ACK packet.
* SCTP Implementors Guide, 2.18 Handling of address
...
...
net/sctp/socket.c
View file @
d7b59481
...
...
@@ -820,7 +820,32 @@ SCTP_STATIC int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
/* If a msg_name has been specified, assume this is to be used. */
if
(
msg_name
)
{
/* Look for a matching association on the endpoint. */
asoc
=
sctp_endpoint_lookup_assoc
(
ep
,
&
to
,
&
transport
);
if
(
!
asoc
)
{
struct
list_head
*
pos
;
struct
sockaddr_storage_list
*
addr
;
sctp_bind_addr_t
*
bp
=
&
ep
->
base
.
bind_addr
;
sctp_read_lock
(
&
ep
->
base
.
addr_lock
);
/* If we could not find a matching association on
* the endpoint, make sure that there is no peeled-
* off association.
*/
list_for_each
(
pos
,
&
bp
->
address_list
)
{
addr
=
list_entry
(
pos
,
struct
sockaddr_storage_list
,
list
);
if
(
sctp_has_association
(
&
addr
->
a
,
&
to
))
{
err
=
-
EINVAL
;
sctp_read_unlock
(
&
ep
->
base
.
addr_lock
);
goto
out_unlock
;
}
}
sctp_read_unlock
(
&
ep
->
base
.
addr_lock
);
}
}
else
{
/* For a peeled-off socket, ignore any associd specified by
* the user with SNDRCVINFO.
...
...
@@ -1583,6 +1608,8 @@ SCTP_STATIC int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newso
sctp_endpoint_t
*
newep
;
sctp_opt_t
*
oldsp
=
sctp_sk
(
oldsk
);
sctp_opt_t
*
newsp
;
struct
sk_buff
*
skb
,
*
tmp
;
sctp_ulpevent_t
*
event
;
int
err
=
0
;
/* An association cannot be branched off from an already peeled-off
...
...
@@ -1612,6 +1639,17 @@ SCTP_STATIC int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newso
*/
newsp
->
ep
=
newep
;
/* Move any messages in the old socket's receive queue that are for the
* peeled off association to the new socket's receive queue.
*/
sctp_skb_for_each
(
skb
,
&
oldsk
->
receive_queue
,
tmp
)
{
event
=
(
sctp_ulpevent_t
*
)
skb
->
cb
;
if
(
event
->
asoc
==
assoc
)
{
__skb_unlink
(
skb
,
skb
->
list
);
__skb_queue_tail
(
&
newsk
->
receive_queue
,
skb
);
}
}
/* Set the type of socket to indicate that it is peeled off from the
* original socket.
*/
...
...
@@ -1629,39 +1667,46 @@ static inline int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval
{
sctp_peeloff_arg_t
peeloff
;
struct
socket
*
newsock
;
int
err
,
sd
;
int
retval
=
0
;
sctp_association_t
*
assoc
;
if
(
len
!=
sizeof
(
sctp_peeloff_arg_t
))
return
-
EINVAL
;
if
(
copy_from_user
(
&
peeloff
,
optval
,
len
))
return
-
EFAULT
;
sctp_lock_sock
(
sk
);
assoc
=
sctp_id2assoc
(
sk
,
peeloff
.
associd
);
if
(
NULL
==
assoc
)
return
-
EINVAL
;
if
(
NULL
==
assoc
)
{
retval
=
-
EINVAL
;
goto
out_unlock
;
}
SCTP_DEBUG_PRINTK
(
"%s: sk: %p assoc: %p
\n
"
,
__FUNCTION__
,
sk
,
assoc
);
err
=
sctp_do_peeloff
(
assoc
,
&
newsock
);
if
(
err
<
0
)
return
err
;
retval
=
sctp_do_peeloff
(
assoc
,
&
newsock
);
if
(
retval
<
0
)
goto
out_unlock
;
/* Map the socket to an unused fd that can be returned to the user. */
sd
=
sock_map_fd
(
newsock
);
if
(
sd
<
0
)
{
retval
=
sock_map_fd
(
newsock
);
if
(
retval
<
0
)
{
sock_release
(
newsock
);
return
sd
;
goto
out_unlock
;
}
SCTP_DEBUG_PRINTK
(
"%s: sk: %p assoc: %p newsk: %p sd: %d
\n
"
,
__FUNCTION__
,
sk
,
assoc
,
newsock
->
sk
,
sd
);
__FUNCTION__
,
sk
,
assoc
,
newsock
->
sk
,
retval
);
/* Return the fd mapped to the new socket. */
peeloff
.
sd
=
sd
;
peeloff
.
sd
=
retval
;
if
(
copy_to_user
(
optval
,
&
peeloff
,
len
))
ret
urn
-
EFAULT
;
ret
val
=
-
EFAULT
;
return
0
;
out_unlock:
sctp_release_sock
(
sk
);
return
retval
;
}
SCTP_STATIC
int
sctp_getsockopt
(
struct
sock
*
sk
,
int
level
,
int
optname
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment