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
9d899ea3
Commit
9d899ea3
authored
Apr 25, 2003
by
Sridhar Samudrala
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[SCTP] sctp_sendmsg() updates for TCP-style sockets.
parent
d1256358
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
55 additions
and
48 deletions
+55
-48
net/sctp/associola.c
net/sctp/associola.c
+3
-4
net/sctp/endpointola.c
net/sctp/endpointola.c
+1
-2
net/sctp/output.c
net/sctp/output.c
+2
-3
net/sctp/sm_sideeffect.c
net/sctp/sm_sideeffect.c
+9
-13
net/sctp/socket.c
net/sctp/socket.c
+40
-26
No files found.
net/sctp/associola.c
View file @
9d899ea3
...
...
@@ -299,8 +299,7 @@ void sctp_association_free(struct sctp_association *asoc)
list_del
(
&
asoc
->
asocs
);
/* Decrement the backlog value for a TCP-style listening socket. */
if
((
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
&&
(
SCTP_SS_LISTENING
==
sk
->
state
))
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
))
sk
->
ack_backlog
--
;
/* Mark as dead, so other users can know this structure is
...
...
@@ -834,7 +833,7 @@ void sctp_assoc_migrate(struct sctp_association *assoc, struct sock *newsk)
list_del
(
&
assoc
->
asocs
);
/* Decrement the backlog value for a TCP-style socket. */
if
(
SCTP_SOCKET_TCP
==
sctp_sk
(
oldsk
)
->
type
)
if
(
sctp_style
(
oldsk
,
TCP
)
)
oldsk
->
ack_backlog
--
;
/* Release references to the old endpoint and the sock. */
...
...
@@ -877,7 +876,7 @@ void sctp_assoc_update(struct sctp_association *asoc,
* current next_tsn in case data sent to peer
* has been discarded and needs retransmission.
*/
if
(
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
{
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
)
{
asoc
->
next_tsn
=
new
->
next_tsn
;
asoc
->
ctsn_ack_point
=
new
->
ctsn_ack_point
;
...
...
net/sctp/endpointola.c
View file @
9d899ea3
...
...
@@ -177,8 +177,7 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep,
list_add_tail
(
&
asoc
->
asocs
,
&
ep
->
asocs
);
/* Increment the backlog value for a TCP-style listening socket. */
if
((
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
&&
(
SCTP_SS_LISTENING
==
sk
->
state
))
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
))
sk
->
ack_backlog
++
;
}
...
...
net/sctp/output.c
View file @
9d899ea3
...
...
@@ -456,8 +456,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
tp
->
last_time_used
=
jiffies
;
/* Restart the AUTOCLOSE timer when sending data. */
if
((
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
&&
(
asoc
->
autoclose
))
{
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
&&
asoc
->
autoclose
)
{
timer
=
&
asoc
->
timers
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
];
timeout
=
asoc
->
timeouts
[
SCTP_EVENT_TIMEOUT_AUTOCLOSE
];
...
...
@@ -608,7 +607,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
* unacknowledged.
*/
if
(
!
sp
->
nodelay
&&
SCTP_IP_OVERHEAD
==
packet
->
size
&&
q
->
outstanding_bytes
&&
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
{
q
->
outstanding_bytes
&&
sctp_state
(
asoc
,
ESTABLISHED
)
)
{
unsigned
len
=
datasize
+
q
->
out_qlen
;
/* Check whether this chunk and all the rest of pending
...
...
net/sctp/sm_sideeffect.c
View file @
9d899ea3
...
...
@@ -610,30 +610,27 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds,
static
void
sctp_cmd_new_state
(
sctp_cmd_seq_t
*
cmds
,
struct
sctp_association
*
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
;
if
(
SCTP_SOCKET_TCP
==
sp
->
type
)
{
if
(
sctp_style
(
sk
,
TCP
)
)
{
/* Change the sk->state of a TCP-style socket that has
* sucessfully completed a connect() call.
*/
if
((
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
&&
(
SCTP_SS_CLOSED
==
sk
->
state
))
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
&&
sctp_sstate
(
sk
,
CLOSED
))
sk
->
state
=
SCTP_SS_ESTABLISHED
;
/* Set the RCV_SHUTDOWN flag when a SHUTDOWN is received. */
if
(
SCTP_STATE_SHUTDOWN_RECEIVED
==
asoc
->
state
)
if
(
sctp_state
(
asoc
,
SHUTDOWN_RECEIVED
)
&&
sctp_sstate
(
sk
,
ESTABLISHED
))
sk
->
shutdown
|=
RCV_SHUTDOWN
;
}
if
(
(
SCTP_STATE_ESTABLISHED
==
asoc
->
state
)
||
(
SCTP_STATE_CLOSED
==
asoc
->
state
)
||
(
SCTP_STATE_SHUTDOWN_RECEIVED
==
asoc
->
state
))
{
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
||
sctp_state
(
asoc
,
CLOSED
)
||
sctp_state
(
asoc
,
SHUTDOWN_RECEIVED
))
{
/* Wake up any processes waiting in the asoc's wait queue in
* sctp_wait_for_connect() or sctp_wait_for_sndbuf().
*/
...
...
@@ -646,7 +643,7 @@ static void sctp_cmd_new_state(sctp_cmd_seq_t *cmds, struct sctp_association *as
* For a UDP-style socket, the waiters are woken up by the
* notifications.
*/
if
(
SCTP_SOCKET_UDP
!=
sp
->
type
)
if
(
!
sctp_style
(
sk
,
UDP
)
)
sk
->
state_change
(
sk
);
}
}
...
...
@@ -661,8 +658,7 @@ static void sctp_cmd_delete_tcb(sctp_cmd_seq_t *cmds,
* listening socket, do not free it so that accept() can pick it
* up later.
*/
if
((
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
&&
(
SCTP_SS_LISTENING
==
sk
->
state
)
&&
(
!
asoc
->
temp
))
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
)
&&
(
!
asoc
->
temp
))
return
;
sctp_unhash_established
(
asoc
);
...
...
net/sctp/socket.c
View file @
9d899ea3
...
...
@@ -794,7 +794,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
SCTP_DEBUG_PRINTK
(
"Using endpoint: %s.
\n
"
,
ep
->
debug_name
);
if
(
sctp_style
(
sk
,
TCP
)
&&
(
SCTP_SS_ESTABLISHED
!=
sk
->
state
))
{
/* We cannot send a message over a TCP-style listening socket. */
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
))
{
err
=
-
EPIPE
;
goto
out_nounlock
;
}
...
...
@@ -843,6 +844,12 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
SCTP_DEBUG_PRINTK
(
"msg_len: %Zd, sinfo_flags: 0x%x
\n
"
,
msg_len
,
sinfo_flags
);
/* MSG_EOF or MSG_ABORT cannot be set on a TCP-style socket. */
if
(
sctp_style
(
sk
,
TCP
)
&&
(
sinfo_flags
&
(
MSG_EOF
|
MSG_ABORT
)))
{
err
=
-
EINVAL
;
goto
out_nounlock
;
}
/* If MSG_EOF is set, no data can be sent. Disallow sending zero
* length messages when MSG_EOF|MSG_ABORT is not set.
* If MSG_ABORT is set, the message length could be non zero with
...
...
@@ -874,10 +881,13 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
asoc
=
sctp_endpoint_lookup_assoc
(
ep
,
&
to
,
&
transport
);
if
(
!
asoc
)
{
/* If we could not find a matching association on the
* endpoint, make sure that there is no peeled-off
* association on another socket.
* endpoint, make sure that it is not a TCP-style
* socket that already has an association or there is
* no peeled-off association on another socket.
*/
if
(
sctp_endpoint_is_peeled_off
(
ep
,
&
to
))
{
if
((
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
ESTABLISHED
))
||
sctp_endpoint_is_peeled_off
(
ep
,
&
to
))
{
err
=
-
EADDRNOTAVAIL
;
goto
out_unlock
;
}
...
...
@@ -885,7 +895,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
else
{
asoc
=
sctp_id2assoc
(
sk
,
associd
);
if
(
!
asoc
)
{
err
=
-
E
INVAL
;
err
=
-
E
PIPE
;
goto
out_unlock
;
}
}
...
...
@@ -1050,11 +1060,12 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto
out_free
;
}
/*
This flag, in the UDP model, requests the SCTP stack to
*
override the primary destination address with the
*
address found with the sendto/sendmsg cal
l.
/*
If an address is passed with the sendto/sendmsg call, it is used
*
to override the primary destination address in the TCP model, or
*
when MSG_ADDR_OVER flag is set in the UDP mode
l.
*/
if
(
sinfo_flags
&
MSG_ADDR_OVER
)
{
if
((
sctp_style
(
sk
,
TCP
)
&&
msg_name
)
||
(
sinfo_flags
&
MSG_ADDR_OVER
))
{
chunk_tp
=
sctp_assoc_lookup_paddr
(
asoc
,
&
to
);
if
(
!
chunk_tp
)
{
err
=
-
EINVAL
;
...
...
@@ -1064,7 +1075,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
chunk_tp
=
NULL
;
/* Auto-connect, if we aren't connected already. */
if
(
SCTP_STATE_CLOSED
==
asoc
->
state
)
{
if
(
sctp_state
(
asoc
,
CLOSED
)
)
{
err
=
sctp_primitive_ASSOCIATE
(
asoc
,
NULL
);
if
(
err
<
0
)
goto
out_free
;
...
...
@@ -1193,7 +1204,7 @@ SCTP_STATIC int sctp_recvmsg(struct kiocb *iocb, struct sock *sk,
sctp_lock_sock
(
sk
);
if
(
sctp_style
(
sk
,
TCP
)
&&
(
SCTP_SS_ESTABLISHED
!=
sk
->
state
))
{
if
(
sctp_style
(
sk
,
TCP
)
&&
!
sctp_sstate
(
sk
,
ESTABLISHED
))
{
err
=
-
ENOTCONN
;
goto
out
;
}
...
...
@@ -2095,7 +2106,7 @@ static int sctp_getsockopt_set_events(struct sock *sk, int len, char *optval, in
static
int
sctp_getsockopt_autoclose
(
struct
sock
*
sk
,
int
len
,
char
*
optval
,
int
*
optlen
)
{
/* Applicable to UDP-style socket only */
if
(
SCTP_SOCKET_TCP
==
sctp_sk
(
sk
)
->
type
)
if
(
sctp_style
(
sk
,
TCP
)
)
return
-
EOPNOTSUPP
;
if
(
len
!=
sizeof
(
int
))
return
-
EINVAL
;
...
...
@@ -2115,7 +2126,7 @@ SCTP_STATIC int sctp_do_peeloff(struct sctp_association *asoc,
/* An association cannot be branched off from an already peeled-off
* socket, nor is this supported for tcp style sockets.
*/
if
(
SCTP_SOCKET_UDP
!=
sctp_sk
(
sk
)
->
type
)
if
(
!
sctp_style
(
sk
,
UDP
)
)
return
-
EINVAL
;
/* Create a new socket. */
...
...
@@ -2861,10 +2872,10 @@ SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
/* Only UDP style sockets that are not peeled off are allowed to
* listen().
*/
if
(
SCTP_SOCKET_UDP
!=
sp
->
type
)
if
(
!
sctp_style
(
sk
,
UDP
)
)
return
-
EINVAL
;
if
(
s
k
->
state
==
SCTP_SS_LISTENING
)
if
(
s
ctp_sstate
(
sk
,
LISTENING
)
)
return
0
;
/*
...
...
@@ -2897,7 +2908,7 @@ SCTP_STATIC int sctp_stream_listen(struct sock *sk, int backlog)
struct
sctp_opt
*
sp
=
sctp_sk
(
sk
);
struct
sctp_endpoint
*
ep
=
sp
->
ep
;
if
(
s
k
->
state
==
SCTP_SS_LISTENING
)
if
(
s
ctp_sstate
(
sk
,
LISTENING
)
)
return
0
;
/*
...
...
@@ -2994,7 +3005,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
/* A TCP-style listening socket becomes readable when the accept queue
* is not empty.
*/
if
(
(
SCTP_SOCKET_TCP
==
sp
->
type
)
&&
(
SCTP_SS_LISTENING
==
sk
->
state
))
if
(
sctp_style
(
sk
,
TCP
)
&&
sctp_sstate
(
sk
,
LISTENING
))
return
(
!
list_empty
(
&
sp
->
ep
->
asocs
))
?
(
POLLIN
|
POLLRDNORM
)
:
0
;
...
...
@@ -3011,11 +3022,9 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
(
sk
->
shutdown
&
RCV_SHUTDOWN
))
mask
|=
POLLIN
|
POLLRDNORM
;
if
(
SCTP_SOCKET_UDP
!=
sctp_sk
(
sk
)
->
type
)
{
/* The association is either gone or not ready. */
if
(
SCTP_SS_CLOSED
==
sk
->
state
)
return
mask
;
}
/* The association is either gone or not ready. */
if
(
!
sctp_style
(
sk
,
UDP
)
&&
sctp_sstate
(
sk
,
CLOSED
))
return
mask
;
/* Is it writable? */
if
(
sctp_writeable
(
sk
))
{
...
...
@@ -3255,8 +3264,7 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p)
error
=
-
ENOTCONN
;
/* Is there a good reason to think that we may receive some data? */
if
((
list_empty
(
&
sctp_sk
(
sk
)
->
ep
->
asocs
))
&&
(
sk
->
state
!=
SCTP_SS_LISTENING
))
if
(
list_empty
(
&
sctp_sk
(
sk
)
->
ep
->
asocs
)
&&
!
sctp_sstate
(
sk
,
LISTENING
))
goto
out
;
/* Handle signals. */
...
...
@@ -3578,7 +3586,7 @@ static int sctp_wait_for_connect(struct sctp_association *asoc, long *timeo_p)
if
(
signal_pending
(
current
))
goto
do_interrupted
;
if
(
asoc
->
state
==
SCTP_STATE_ESTABLISHED
)
if
(
sctp_state
(
asoc
,
ESTABLISHED
)
)
break
;
/* Let another process have a go. Since we are going
...
...
@@ -3633,7 +3641,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo)
}
err
=
-
EINVAL
;
if
(
sk
->
state
!=
SCTP_SS_LISTENING
)
if
(
!
sctp_sstate
(
sk
,
LISTENING
)
)
break
;
err
=
0
;
...
...
@@ -3738,6 +3746,12 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk,
/* Migrate the association to the new socket. */
sctp_assoc_migrate
(
assoc
,
newsk
);
/* If the association on the newsk is already closed before accept()
* is called, set RCV_SHUTDOWN flag.
*/
if
(
sctp_state
(
assoc
,
CLOSED
)
&&
sctp_style
(
newsk
,
TCP
))
newsk
->
shutdown
|=
RCV_SHUTDOWN
;
newsk
->
state
=
SCTP_SS_ESTABLISHED
;
}
...
...
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