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
Kirill Smelkov
linux
Commits
bf953999
Commit
bf953999
authored
Mar 02, 2003
by
Sridhar Samudrala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] accept() support for TCP-style SCTP sockets.
parent
088e723f
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
419 additions
and
101 deletions
+419
-101
include/net/sctp/structs.h
include/net/sctp/structs.h
+2
-0
net/sctp/endpointola.c
net/sctp/endpointola.c
+2
-0
net/sctp/ipv6.c
net/sctp/ipv6.c
+72
-4
net/sctp/protocol.c
net/sctp/protocol.c
+73
-5
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+21
-6
net/sctp/socket.c
net/sctp/socket.c
+247
-84
net/sctp/ulpqueue.c
net/sctp/ulpqueue.c
+2
-2
No files found.
include/net/sctp/structs.h
View file @
bf953999
...
...
@@ -262,6 +262,8 @@ struct sctp_pf {
struct
sctp_opt
*
);
int
(
*
bind_verify
)
(
struct
sctp_opt
*
,
union
sctp_addr
*
);
int
(
*
supported_addrs
)(
const
struct
sctp_opt
*
,
__u16
*
);
struct
sock
*
(
*
create_accept_sk
)
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
);
struct
sctp_af
*
af
;
};
...
...
net/sctp/endpointola.c
View file @
bf953999
...
...
@@ -195,6 +195,8 @@ void sctp_endpoint_destroy(sctp_endpoint_t *ep)
{
SCTP_ASSERT
(
ep
->
base
.
dead
,
"Endpoint is not dead"
,
return
);
ep
->
base
.
sk
->
state
=
SCTP_SS_CLOSED
;
/* Unlink this endpoint, so we can't find it again! */
sctp_unhash_endpoint
(
ep
);
...
...
net/sctp/ipv6.c
View file @
bf953999
...
...
@@ -432,6 +432,62 @@ static sctp_scope_t sctp_v6_scope(union sctp_addr *addr)
return
retval
;
}
/* Create and initialize a new sk for the socket to be returned by accept(). */
struct
sock
*
sctp_v6_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
{
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
sock
*
newsk
;
struct
inet_opt
*
newinet
;
struct
ipv6_pinfo
*
newnp
,
*
np
=
inet6_sk
(
sk
);
struct
sctp6_sock
*
newsctp6sk
;
newsk
=
sk_alloc
(
PF_INET6
,
GFP_KERNEL
,
sizeof
(
struct
sctp6_sock
),
sk
->
slab
);
if
(
!
newsk
)
goto
out
;
sock_init_data
(
NULL
,
newsk
);
newsk
->
type
=
SOCK_STREAM
;
newsk
->
prot
=
sk
->
prot
;
newsk
->
no_check
=
sk
->
no_check
;
newsk
->
reuse
=
sk
->
reuse
;
newsk
->
destruct
=
inet_sock_destruct
;
newsk
->
zapped
=
0
;
newsk
->
family
=
PF_INET6
;
newsk
->
protocol
=
IPPROTO_SCTP
;
newsk
->
backlog_rcv
=
sk
->
prot
->
backlog_rcv
;
newsctp6sk
=
(
struct
sctp6_sock
*
)
newsk
;
newsctp6sk
->
pinet6
=
&
newsctp6sk
->
inet6
;
newinet
=
inet_sk
(
newsk
);
newnp
=
inet6_sk
(
newsk
);
memcpy
(
newnp
,
np
,
sizeof
(
struct
ipv6_pinfo
));
ipv6_addr_copy
(
&
newnp
->
daddr
,
&
asoc
->
peer
.
primary_addr
.
v6
.
sin6_addr
);
newinet
->
sport
=
inet
->
sport
;
newinet
->
dport
=
asoc
->
peer
.
port
;
#ifdef INET_REFCNT_DEBUG
atomic_inc
(
&
inet6_sock_nr
);
atomic_inc
(
&
inet_sock_nr
);
#endif
if
(
0
!=
newsk
->
prot
->
init
(
newsk
))
{
inet_sock_release
(
newsk
);
newsk
=
NULL
;
}
out:
return
newsk
;
}
/* Initialize a PF_INET6 socket msg_name. */
static
void
sctp_inet6_msgname
(
char
*
msgname
,
int
*
addr_len
)
{
...
...
@@ -597,7 +653,7 @@ static struct proto_ops inet6_seqpacket_ops = {
.
mmap
=
sock_no_mmap
,
};
static
struct
inet_protosw
sctpv6_protosw
=
{
static
struct
inet_protosw
sctpv6_
seqpacket_
protosw
=
{
.
type
=
SOCK_SEQPACKET
,
.
protocol
=
IPPROTO_SCTP
,
.
prot
=
&
sctp_prot
,
...
...
@@ -606,6 +662,15 @@ static struct inet_protosw sctpv6_protosw = {
.
no_check
=
0
,
.
flags
=
SCTP_PROTOSW_FLAG
};
static
struct
inet_protosw
sctpv6_stream_protosw
=
{
.
type
=
SOCK_STREAM
,
.
protocol
=
IPPROTO_SCTP
,
.
prot
=
&
sctp_prot
,
.
ops
=
&
inet6_seqpacket_ops
,
.
capability
=
-
1
,
.
no_check
=
0
,
.
flags
=
SCTP_PROTOSW_FLAG
};
static
struct
inet6_protocol
sctpv6_protocol
=
{
.
handler
=
sctp_rcv
,
...
...
@@ -641,6 +706,7 @@ static struct sctp_pf sctp_pf_inet6_specific = {
.
cmp_addr
=
sctp_inet6_cmp_addr
,
.
bind_verify
=
sctp_inet6_bind_verify
,
.
supported_addrs
=
sctp_inet6_supported_addrs
,
.
create_accept_sk
=
sctp_v6_create_accept_sk
,
.
af
=
&
sctp_ipv6_specific
,
};
...
...
@@ -651,8 +717,9 @@ int sctp_v6_init(void)
if
(
inet6_add_protocol
(
&
sctpv6_protocol
,
IPPROTO_SCTP
)
<
0
)
return
-
EAGAIN
;
/* Add SCTPv6 to inetsw6 linked list. */
inet6_register_protosw
(
&
sctpv6_protosw
);
/* Add SCTPv6(UDP and TCP style) to inetsw6 linked list. */
inet6_register_protosw
(
&
sctpv6_seqpacket_protosw
);
inet6_register_protosw
(
&
sctpv6_stream_protosw
);
/* Register the SCTP specfic PF_INET6 functions. */
sctp_register_pf
(
&
sctp_pf_inet6_specific
,
PF_INET6
);
...
...
@@ -671,6 +738,7 @@ void sctp_v6_exit(void)
{
list_del
(
&
sctp_ipv6_specific
.
list
);
inet6_del_protocol
(
&
sctpv6_protocol
,
IPPROTO_SCTP
);
inet6_unregister_protosw
(
&
sctpv6_protosw
);
inet6_unregister_protosw
(
&
sctpv6_seqpacket_protosw
);
inet6_unregister_protosw
(
&
sctpv6_stream_protosw
);
unregister_inet6addr_notifier
(
&
sctp_inetaddr_notifier
);
}
net/sctp/protocol.c
View file @
bf953999
...
...
@@ -480,6 +480,61 @@ void sctp_v4_get_saddr(sctp_association_t *asoc,
}
/* Create and initialize a new sk for the socket returned by accept(). */
struct
sock
*
sctp_v4_create_accept_sk
(
struct
sock
*
sk
,
struct
sctp_association
*
asoc
)
{
struct
sock
*
newsk
;
struct
inet_opt
*
inet
=
inet_sk
(
sk
);
struct
inet_opt
*
newinet
;
newsk
=
sk_alloc
(
PF_INET
,
GFP_KERNEL
,
sizeof
(
struct
sctp_sock
),
sk
->
slab
);
if
(
!
newsk
)
goto
out
;
sock_init_data
(
NULL
,
newsk
);
newsk
->
type
=
SOCK_STREAM
;
newsk
->
prot
=
sk
->
prot
;
newsk
->
no_check
=
sk
->
no_check
;
newsk
->
reuse
=
sk
->
reuse
;
newsk
->
destruct
=
inet_sock_destruct
;
newsk
->
zapped
=
0
;
newsk
->
family
=
PF_INET
;
newsk
->
protocol
=
IPPROTO_SCTP
;
newsk
->
backlog_rcv
=
sk
->
prot
->
backlog_rcv
;
newinet
=
inet_sk
(
newsk
);
newinet
->
sport
=
inet
->
sport
;
newinet
->
saddr
=
inet
->
saddr
;
newinet
->
rcv_saddr
=
inet
->
saddr
;
newinet
->
dport
=
asoc
->
peer
.
port
;
newinet
->
daddr
=
asoc
->
peer
.
primary_addr
.
v4
.
sin_addr
.
s_addr
;
newinet
->
pmtudisc
=
inet
->
pmtudisc
;
newinet
->
id
=
0
;
newinet
->
ttl
=
sysctl_ip_default_ttl
;
newinet
->
mc_loop
=
1
;
newinet
->
mc_ttl
=
1
;
newinet
->
mc_index
=
0
;
newinet
->
mc_list
=
NULL
;
#ifdef INET_REFCNT_DEBUG
atomic_inc
(
&
inet_sock_nr
);
#endif
if
(
0
!=
newsk
->
prot
->
init
(
newsk
))
{
inet_sock_release
(
newsk
);
newsk
=
NULL
;
}
out:
return
newsk
;
}
/* Event handler for inet address addition/deletion events.
* Basically, whenever there is an event, we re-build our local address list.
*/
...
...
@@ -664,6 +719,7 @@ static struct sctp_pf sctp_pf_inet = {
.
cmp_addr
=
sctp_inet_cmp_addr
,
.
bind_verify
=
sctp_inet_bind_verify
,
.
supported_addrs
=
sctp_inet_supported_addrs
,
.
create_accept_sk
=
sctp_v4_create_accept_sk
,
.
af
=
&
sctp_ipv4_specific
,
};
...
...
@@ -694,7 +750,7 @@ struct proto_ops inet_seqpacket_ops = {
};
/* Registration with AF_INET family. */
st
ruct
inet_protosw
sctp
_protosw
=
{
st
atic
struct
inet_protosw
sctp_seqpacket
_protosw
=
{
.
type
=
SOCK_SEQPACKET
,
.
protocol
=
IPPROTO_SCTP
,
.
prot
=
&
sctp_prot
,
...
...
@@ -703,6 +759,15 @@ struct inet_protosw sctp_protosw = {
.
no_check
=
0
,
.
flags
=
SCTP_PROTOSW_FLAG
};
static
struct
inet_protosw
sctp_stream_protosw
=
{
.
type
=
SOCK_STREAM
,
.
protocol
=
IPPROTO_SCTP
,
.
prot
=
&
sctp_prot
,
.
ops
=
&
inet_seqpacket_ops
,
.
capability
=
-
1
,
.
no_check
=
0
,
.
flags
=
SCTP_PROTOSW_FLAG
};
/* Register with IP layer. */
static
struct
inet_protocol
sctp_protocol
=
{
...
...
@@ -809,8 +874,9 @@ __init int sctp_init(void)
if
(
inet_add_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
)
<
0
)
return
-
EAGAIN
;
/* Add SCTP to inetsw linked list. */
inet_register_protosw
(
&
sctp_protosw
);
/* Add SCTP(TCP and UDP style) to inetsw linked list. */
inet_register_protosw
(
&
sctp_seqpacket_protosw
);
inet_register_protosw
(
&
sctp_stream_protosw
);
/* Allocate and initialise sctp mibs. */
status
=
init_sctp_mibs
();
...
...
@@ -956,7 +1022,8 @@ __init int sctp_init(void)
cleanup_sctp_mibs
();
err_init_mibs:
inet_del_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
);
inet_unregister_protosw
(
&
sctp_protosw
);
inet_unregister_protosw
(
&
sctp_seqpacket_protosw
);
inet_unregister_protosw
(
&
sctp_stream_protosw
);
return
status
;
}
...
...
@@ -989,7 +1056,8 @@ __exit void sctp_exit(void)
cleanup_sctp_mibs
();
inet_del_protocol
(
&
sctp_protocol
,
IPPROTO_SCTP
);
inet_unregister_protosw
(
&
sctp_protosw
);
inet_unregister_protosw
(
&
sctp_seqpacket_protosw
);
inet_unregister_protosw
(
&
sctp_stream_protosw
);
}
module_init
(
sctp_init
);
...
...
net/sctp/sm_sideeffect.c
View file @
bf953999
...
...
@@ -1223,13 +1223,28 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds, sctp_association_t *asoc,
static
void
sctp_cmd_new_state
(
sctp_cmd_seq_t
*
cmds
,
sctp_association_t
*
asoc
,
sctp_state_t
state
)
{
struct
sock
*
sk
=
asoc
->
base
.
sk
;
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
asoc
->
state
=
state
;
asoc
->
state_timestamp
=
jiffies
;
/* Wake up any process waiting for the association to
* get established.
*/
if
((
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
&&
(
waitqueue_active
(
&
asoc
->
wait
)))
wake_up_interruptible
(
&
asoc
->
wait
);
if
((
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
||
(
SCTP_STATE_CLOSED
==
asoc
->
state
))
{
/* Wake up any processes waiting in the asoc's wait queue in
* sctp_wait_for_connect() or sctp_wait_for_sndbuf().
*/
if
(
waitqueue_active
(
&
asoc
->
wait
))
wake_up_interruptible
(
&
asoc
->
wait
);
/* Wake up any processes waiting in the sk's sleep queue of
* a tcp-style or udp-style peeled-off socket in
* sctp_wait_for_accept() or sctp_wait_for_packet().
* For a udp-style socket, the waiters are woken up by the
* notifications.
*/
if
(
sp
->
type
!=
SCTP_SOCKET_UDP
)
sk
->
state_change
(
sk
);
}
}
net/sctp/socket.c
View file @
bf953999
This diff is collapsed.
Click to expand it.
net/sctp/ulpqueue.c
View file @
bf953999
...
...
@@ -230,7 +230,7 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
sctp_ulpq_clear_pd
(
ulpq
);
if
(
queue
==
&
sk
->
receive_queue
)
wake_up_interruptible
(
sk
->
sleep
);
sk
->
data_ready
(
sk
,
0
);
return
1
;
out_free:
...
...
@@ -790,5 +790,5 @@ void sctp_ulpq_abort_pd(struct sctp_ulpq *ulpq, int priority)
/* If there is data waiting, send it up the socket now. */
if
(
sctp_ulpq_clear_pd
(
ulpq
)
||
ev
)
wake_up_interruptible
(
sk
->
sleep
);
sk
->
data_ready
(
sk
,
0
);
}
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