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
9fe16ce7
Commit
9fe16ce7
authored
May 12, 2003
by
Sridhar Samudrala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] Support for socket options that pass both addr and associd.
parent
da8879d2
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
99 additions
and
61 deletions
+99
-61
include/net/sctp/structs.h
include/net/sctp/structs.h
+10
-7
net/sctp/associola.c
net/sctp/associola.c
+6
-0
net/sctp/socket.c
net/sctp/socket.c
+83
-54
No files found.
include/net/sctp/structs.h
View file @
9fe16ce7
...
@@ -289,6 +289,10 @@ struct sctp_opt {
...
@@ -289,6 +289,10 @@ struct sctp_opt {
/* Various Socket Options. */
/* Various Socket Options. */
__u16
default_stream
;
__u16
default_stream
;
__u32
default_ppid
;
__u32
default_ppid
;
__u16
default_flags
;
__u32
default_context
;
__u32
default_timetolive
;
struct
sctp_initmsg
initmsg
;
struct
sctp_initmsg
initmsg
;
struct
sctp_rtoinfo
rtoinfo
;
struct
sctp_rtoinfo
rtoinfo
;
struct
sctp_paddrparams
paddrparam
;
struct
sctp_paddrparams
paddrparam
;
...
@@ -1492,13 +1496,12 @@ struct sctp_association {
...
@@ -1492,13 +1496,12 @@ struct sctp_association {
*/
*/
int
counters
[
SCTP_NUMBER_COUNTERS
];
int
counters
[
SCTP_NUMBER_COUNTERS
];
struct
{
/* Default send parameters. */
__u16
stream
;
__u16
default_stream
;
__u16
flags
;
__u16
default_flags
;
__u32
ppid
;
__u32
default_ppid
;
__u32
context
;
__u32
default_context
;
__u32
timetolive
;
__u32
default_timetolive
;
}
defaults
;
/* This tracks outbound ssn for a given stream. */
/* This tracks outbound ssn for a given stream. */
struct
sctp_ssnmap
*
ssnmap
;
struct
sctp_ssnmap
*
ssnmap
;
...
...
net/sctp/associola.c
View file @
9fe16ce7
...
@@ -277,6 +277,12 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
...
@@ -277,6 +277,12 @@ struct sctp_association *sctp_association_init(struct sctp_association *asoc,
asoc
->
autoclose
=
sp
->
autoclose
;
asoc
->
autoclose
=
sp
->
autoclose
;
asoc
->
default_stream
=
sp
->
default_stream
;
asoc
->
default_ppid
=
sp
->
default_ppid
;
asoc
->
default_flags
=
sp
->
default_flags
;
asoc
->
default_context
=
sp
->
default_context
;
asoc
->
default_timetolive
=
sp
->
default_timetolive
;
return
asoc
;
return
asoc
;
fail_init:
fail_init:
...
...
net/sctp/socket.c
View file @
9fe16ce7
...
@@ -108,10 +108,16 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
...
@@ -108,10 +108,16 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
{
{
struct
sctp_association
*
asoc
=
NULL
;
struct
sctp_association
*
asoc
=
NULL
;
/* If this is not a UDP-style socket, assoc id should be
/* If this is not a UDP-style socket, assoc id should be ignored. */
* ignored.
*/
if
(
!
sctp_style
(
sk
,
UDP
))
{
if
(
!
sctp_style
(
sk
,
UDP
))
{
/* Return NULL if the socket state is not ESTABLISHED. It
* could be a TCP-style listening socket or a socket which
* hasn't yet called connect() to establish an association.
*/
if
(
!
sctp_sstate
(
sk
,
ESTABLISHED
))
return
NULL
;
/* Get the first and the only association from the list. */
if
(
!
list_empty
(
&
sctp_sk
(
sk
)
->
ep
->
asocs
))
if
(
!
list_empty
(
&
sctp_sk
(
sk
)
->
ep
->
asocs
))
asoc
=
list_entry
(
sctp_sk
(
sk
)
->
ep
->
asocs
.
next
,
asoc
=
list_entry
(
sctp_sk
(
sk
)
->
ep
->
asocs
.
next
,
struct
sctp_association
,
asocs
);
struct
sctp_association
,
asocs
);
...
@@ -134,6 +140,30 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
...
@@ -134,6 +140,30 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id)
return
asoc
;
return
asoc
;
}
}
/* Look up the transport from an address and an assoc id. If both address and
* id are specified, the associations matching the address and the id should be
* the same.
*/
struct
sctp_transport
*
sctp_addr_id2transport
(
struct
sock
*
sk
,
struct
sockaddr_storage
*
addr
,
sctp_assoc_t
id
)
{
struct
sctp_association
*
addr_asoc
=
NULL
,
*
id_asoc
=
NULL
;
struct
sctp_transport
*
transport
;
addr_asoc
=
sctp_endpoint_lookup_assoc
(
sctp_sk
(
sk
)
->
ep
,
(
union
sctp_addr
*
)
addr
,
&
transport
);
if
(
!
addr_asoc
)
return
NULL
;
id_asoc
=
sctp_id2assoc
(
sk
,
id
);
if
(
id_asoc
&&
(
id_asoc
!=
addr_asoc
))
return
NULL
;
return
transport
;
}
/* API 3.1.2 bind() - UDP Style Syntax
/* API 3.1.2 bind() - UDP Style Syntax
* The syntax of bind() is,
* The syntax of bind() is,
*
*
...
@@ -712,7 +742,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
...
@@ -712,7 +742,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
list_head
*
pos
,
*
temp
;
struct
list_head
*
pos
,
*
temp
;
printk
(
"sctp_close(sk: 0x%p, timeout:%ld)
\n
"
,
sk
,
timeout
);
SCTP_DEBUG_PRINTK
(
"sctp_close(sk: 0x%p, timeout:%ld)
\n
"
,
sk
,
timeout
);
sctp_lock_sock
(
sk
);
sctp_lock_sock
(
sk
);
sk
->
shutdown
=
SHUTDOWN_MASK
;
sk
->
shutdown
=
SHUTDOWN_MASK
;
...
@@ -1063,11 +1093,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
...
@@ -1063,11 +1093,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
/* If the user didn't specify SNDRCVINFO, make up one with
/* If the user didn't specify SNDRCVINFO, make up one with
* some defaults.
* some defaults.
*/
*/
default_sinfo
.
sinfo_stream
=
asoc
->
default
s
.
stream
;
default_sinfo
.
sinfo_stream
=
asoc
->
default
_
stream
;
default_sinfo
.
sinfo_flags
=
asoc
->
default
s
.
flags
;
default_sinfo
.
sinfo_flags
=
asoc
->
default
_
flags
;
default_sinfo
.
sinfo_ppid
=
asoc
->
default
s
.
ppid
;
default_sinfo
.
sinfo_ppid
=
asoc
->
default
_
ppid
;
default_sinfo
.
sinfo_context
=
asoc
->
default
s
.
context
;
default_sinfo
.
sinfo_context
=
asoc
->
default
_
context
;
default_sinfo
.
sinfo_timetolive
=
asoc
->
default
s
.
timetolive
;
default_sinfo
.
sinfo_timetolive
=
asoc
->
default
_
timetolive
;
default_sinfo
.
sinfo_assoc_id
=
sctp_assoc2id
(
asoc
);
default_sinfo
.
sinfo_assoc_id
=
sctp_assoc2id
(
asoc
);
sinfo
=
&
default_sinfo
;
sinfo
=
&
default_sinfo
;
}
}
...
@@ -1382,8 +1412,6 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
...
@@ -1382,8 +1412,6 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
char
*
optval
,
int
optlen
)
char
*
optval
,
int
optlen
)
{
{
struct
sctp_paddrparams
params
;
struct
sctp_paddrparams
params
;
struct
sctp_association
*
asoc
;
union
sctp_addr
*
addr
;
struct
sctp_transport
*
trans
;
struct
sctp_transport
*
trans
;
int
error
;
int
error
;
...
@@ -1392,15 +1420,10 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
...
@@ -1392,15 +1420,10 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
if
(
copy_from_user
(
&
params
,
optval
,
optlen
))
if
(
copy_from_user
(
&
params
,
optval
,
optlen
))
return
-
EFAULT
;
return
-
EFAULT
;
asoc
=
sctp_id2assoc
(
sk
,
params
.
spp_assoc_id
);
trans
=
sctp_addr_id2transport
(
sk
,
&
params
.
spp_address
,
if
(
!
asoc
)
params
.
spp_assoc_id
);
return
-
EINVAL
;
addr
=
(
union
sctp_addr
*
)
&
(
params
.
spp_address
);
trans
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
if
(
!
trans
)
if
(
!
trans
)
return
-
E
NOENT
;
return
-
E
INVAL
;
/* Applications can enable or disable heartbeats for any peer address
/* Applications can enable or disable heartbeats for any peer address
* of an association, modify an address's heartbeat interval, force a
* of an association, modify an address's heartbeat interval, force a
...
@@ -1414,7 +1437,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
...
@@ -1414,7 +1437,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
* and the current interval should remain unchanged.
* and the current interval should remain unchanged.
*/
*/
if
(
0xffffffff
==
params
.
spp_hbinterval
)
{
if
(
0xffffffff
==
params
.
spp_hbinterval
)
{
error
=
sctp_primitive_REQUESTHEARTBEAT
(
asoc
,
trans
);
error
=
sctp_primitive_REQUESTHEARTBEAT
(
trans
->
asoc
,
trans
);
if
(
error
)
if
(
error
)
return
error
;
return
error
;
}
else
{
}
else
{
...
@@ -1465,6 +1488,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
...
@@ -1465,6 +1488,7 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
{
{
struct
sctp_sndrcvinfo
info
;
struct
sctp_sndrcvinfo
info
;
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
optlen
!=
sizeof
(
struct
sctp_sndrcvinfo
))
if
(
optlen
!=
sizeof
(
struct
sctp_sndrcvinfo
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -1472,14 +1496,23 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
...
@@ -1472,14 +1496,23 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
return
-
EFAULT
;
return
-
EFAULT
;
asoc
=
sctp_id2assoc
(
sk
,
info
.
sinfo_assoc_id
);
asoc
=
sctp_id2assoc
(
sk
,
info
.
sinfo_assoc_id
);
if
(
!
asoc
)
if
(
!
asoc
&&
info
.
sinfo_assoc_id
&&
sctp_style
(
sk
,
UDP
)
)
return
-
EINVAL
;
return
-
EINVAL
;
asoc
->
defaults
.
stream
=
info
.
sinfo_stream
;
if
(
asoc
)
{
asoc
->
defaults
.
flags
=
info
.
sinfo_flags
;
asoc
->
default_stream
=
info
.
sinfo_stream
;
asoc
->
defaults
.
ppid
=
info
.
sinfo_ppid
;
asoc
->
default_flags
=
info
.
sinfo_flags
;
asoc
->
defaults
.
context
=
info
.
sinfo_context
;
asoc
->
default_ppid
=
info
.
sinfo_ppid
;
asoc
->
defaults
.
timetolive
=
info
.
sinfo_timetolive
;
asoc
->
default_context
=
info
.
sinfo_context
;
asoc
->
default_timetolive
=
info
.
sinfo_timetolive
;
}
else
{
sp
->
default_stream
=
info
.
sinfo_stream
;
sp
->
default_flags
=
info
.
sinfo_flags
;
sp
->
default_ppid
=
info
.
sinfo_ppid
;
sp
->
default_context
=
info
.
sinfo_context
;
sp
->
default_timetolive
=
info
.
sinfo_timetolive
;
}
return
0
;
return
0
;
}
}
...
@@ -1492,8 +1525,6 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
...
@@ -1492,8 +1525,6 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
static
int
sctp_setsockopt_peer_prim
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
static
int
sctp_setsockopt_peer_prim
(
struct
sock
*
sk
,
char
*
optval
,
int
optlen
)
{
{
struct
sctp_setpeerprim
prim
;
struct
sctp_setpeerprim
prim
;
struct
sctp_association
*
asoc
;
union
sctp_addr
*
addr
;
struct
sctp_transport
*
trans
;
struct
sctp_transport
*
trans
;
if
(
optlen
!=
sizeof
(
struct
sctp_setpeerprim
))
if
(
optlen
!=
sizeof
(
struct
sctp_setpeerprim
))
...
@@ -1502,18 +1533,11 @@ static int sctp_setsockopt_peer_prim(struct sock *sk, char *optval, int optlen)
...
@@ -1502,18 +1533,11 @@ static int sctp_setsockopt_peer_prim(struct sock *sk, char *optval, int optlen)
if
(
copy_from_user
(
&
prim
,
optval
,
sizeof
(
struct
sctp_setpeerprim
)))
if
(
copy_from_user
(
&
prim
,
optval
,
sizeof
(
struct
sctp_setpeerprim
)))
return
-
EFAULT
;
return
-
EFAULT
;
asoc
=
sctp_id2assoc
(
sk
,
prim
.
sspp_assoc_id
);
trans
=
sctp_addr_id2transport
(
sk
,
&
prim
.
sspp_addr
,
prim
.
sspp_assoc_id
);
if
(
!
asoc
)
return
-
EINVAL
;
/* Find the requested address. */
addr
=
(
union
sctp_addr
*
)
&
(
prim
.
sspp_addr
);
trans
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
if
(
!
trans
)
if
(
!
trans
)
return
-
E
NOENT
;
return
-
E
INVAL
;
sctp_assoc_set_primary
(
asoc
,
trans
);
sctp_assoc_set_primary
(
trans
->
asoc
,
trans
);
return
0
;
return
0
;
}
}
...
@@ -1935,6 +1959,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
...
@@ -1935,6 +1959,9 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
*/
*/
sp
->
default_stream
=
0
;
sp
->
default_stream
=
0
;
sp
->
default_ppid
=
0
;
sp
->
default_ppid
=
0
;
sp
->
default_flags
=
0
;
sp
->
default_context
=
0
;
sp
->
default_timetolive
=
0
;
/* Initialize default setup parameters. These parameters
/* Initialize default setup parameters. These parameters
* can be modified with the SCTP_INITMSG socket option or
* can be modified with the SCTP_INITMSG socket option or
...
@@ -2246,8 +2273,6 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
...
@@ -2246,8 +2273,6 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
char
*
optval
,
int
*
optlen
)
char
*
optval
,
int
*
optlen
)
{
{
struct
sctp_paddrparams
params
;
struct
sctp_paddrparams
params
;
struct
sctp_association
*
asoc
;
union
sctp_addr
*
addr
;
struct
sctp_transport
*
trans
;
struct
sctp_transport
*
trans
;
if
(
len
!=
sizeof
(
struct
sctp_paddrparams
))
if
(
len
!=
sizeof
(
struct
sctp_paddrparams
))
...
@@ -2255,15 +2280,10 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
...
@@ -2255,15 +2280,10 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
if
(
copy_from_user
(
&
params
,
optval
,
*
optlen
))
if
(
copy_from_user
(
&
params
,
optval
,
*
optlen
))
return
-
EFAULT
;
return
-
EFAULT
;
asoc
=
sctp_id2assoc
(
sk
,
params
.
spp_assoc_id
);
trans
=
sctp_addr_id2transport
(
sk
,
&
params
.
spp_address
,
if
(
!
asoc
)
params
.
spp_assoc_id
);
return
-
EINVAL
;
addr
=
(
union
sctp_addr
*
)
&
(
params
.
spp_address
);
trans
=
sctp_assoc_lookup_paddr
(
asoc
,
addr
);
if
(
!
trans
)
if
(
!
trans
)
return
-
E
NOENT
;
return
-
E
INVAL
;
/* The value of the heartbeat interval, in milliseconds. A value of 0,
/* The value of the heartbeat interval, in milliseconds. A value of 0,
* when modifying the parameter, specifies that the heartbeat on this
* when modifying the parameter, specifies that the heartbeat on this
...
@@ -2513,6 +2533,7 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
...
@@ -2513,6 +2533,7 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
{
{
struct
sctp_sndrcvinfo
info
;
struct
sctp_sndrcvinfo
info
;
struct
sctp_association
*
asoc
;
struct
sctp_association
*
asoc
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
if
(
len
!=
sizeof
(
struct
sctp_sndrcvinfo
))
if
(
len
!=
sizeof
(
struct
sctp_sndrcvinfo
))
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -2520,14 +2541,22 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
...
@@ -2520,14 +2541,22 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
return
-
EFAULT
;
return
-
EFAULT
;
asoc
=
sctp_id2assoc
(
sk
,
info
.
sinfo_assoc_id
);
asoc
=
sctp_id2assoc
(
sk
,
info
.
sinfo_assoc_id
);
if
(
!
asoc
)
if
(
!
asoc
&&
info
.
sinfo_assoc_id
&&
sctp_style
(
sk
,
UDP
)
)
return
-
EINVAL
;
return
-
EINVAL
;
info
.
sinfo_stream
=
asoc
->
defaults
.
stream
;
if
(
asoc
)
{
info
.
sinfo_flags
=
asoc
->
defaults
.
flags
;
info
.
sinfo_stream
=
asoc
->
default_stream
;
info
.
sinfo_ppid
=
asoc
->
defaults
.
ppid
;
info
.
sinfo_flags
=
asoc
->
default_flags
;
info
.
sinfo_context
=
asoc
->
defaults
.
context
;
info
.
sinfo_ppid
=
asoc
->
default_ppid
;
info
.
sinfo_timetolive
=
asoc
->
defaults
.
timetolive
;
info
.
sinfo_context
=
asoc
->
default_context
;
info
.
sinfo_timetolive
=
asoc
->
default_timetolive
;
}
else
{
info
.
sinfo_stream
=
sp
->
default_stream
;
info
.
sinfo_flags
=
sp
->
default_flags
;
info
.
sinfo_ppid
=
sp
->
default_ppid
;
info
.
sinfo_context
=
sp
->
default_context
;
info
.
sinfo_timetolive
=
sp
->
default_timetolive
;
}
if
(
copy_to_user
(
optval
,
&
info
,
sizeof
(
struct
sctp_sndrcvinfo
)))
if
(
copy_to_user
(
optval
,
&
info
,
sizeof
(
struct
sctp_sndrcvinfo
)))
return
-
EFAULT
;
return
-
EFAULT
;
...
...
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