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
0c336e6d
Commit
0c336e6d
authored
May 01, 2003
by
Jon Grimm
Browse files
Options
Browse Files
Download
Plain Diff
Merge
http://linux-lksctp.bkbits.net/lksctp-2.5.work
into touki.austin.ibm.com:/home/jgrimm/bk/lksctp-2.5.work
parents
62dca1b4
c5d01dcf
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
119 additions
and
60 deletions
+119
-60
include/net/sctp/structs.h
include/net/sctp/structs.h
+25
-18
net/sctp/chunk.c
net/sctp/chunk.c
+43
-7
net/sctp/output.c
net/sctp/output.c
+3
-0
net/sctp/outqueue.c
net/sctp/outqueue.c
+24
-25
net/sctp/sm_make_chunk.c
net/sctp/sm_make_chunk.c
+1
-1
net/sctp/sm_statefuns.c
net/sctp/sm_statefuns.c
+2
-1
net/sctp/socket.c
net/sctp/socket.c
+9
-6
net/sctp/ulpevent.c
net/sctp/ulpevent.c
+12
-2
No files found.
include/net/sctp/structs.h
View file @
0c336e6d
...
...
@@ -459,9 +459,13 @@ struct sctp_datamsg {
struct
list_head
track
;
/* Reference counting. */
atomic_t
refcnt
;
/* When is this message no longer interesting to the peer? */
unsigned
long
expires_at
;
/* Did the messenge fail to send? */
int
send_error
;
char
send_failed
;
/* Control whether fragments from this message can expire. */
char
can_expire
;
};
struct
sctp_datamsg
*
sctp_datamsg_from_user
(
struct
sctp_association
*
,
...
...
@@ -473,6 +477,9 @@ void sctp_datamsg_hold(struct sctp_datamsg *);
void
sctp_datamsg_free
(
struct
sctp_datamsg
*
);
void
sctp_datamsg_track
(
struct
sctp_chunk
*
);
void
sctp_datamsg_assign
(
struct
sctp_datamsg
*
,
struct
sctp_chunk
*
);
void
sctp_datamsg_fail
(
struct
sctp_chunk
*
,
int
error
);
int
sctp_datamsg_expires
(
struct
sctp_chunk
*
);
/* RFC2960 1.4 Key Terms
*
...
...
@@ -545,18 +552,6 @@ struct sctp_chunk {
/* We fill this in if we are calculating RTT. */
unsigned
long
sent_at
;
__u8
rtt_in_progress
;
/* Is this chunk used for RTT calculation? */
__u8
resent
;
/* Has this chunk ever been retransmitted. */
__u8
has_tsn
;
/* Does this chunk have a TSN yet? */
__u8
has_ssn
;
/* Does this chunk have a SSN yet? */
__u8
singleton
;
/* Was this the only chunk in the packet? */
__u8
end_of_packet
;
/* Was this the last chunk in the packet? */
__u8
ecn_ce_done
;
/* Have we processed the ECN CE bit? */
__u8
pdiscard
;
/* Discard the whole packet now? */
__u8
tsn_gap_acked
;
/* Is this chunk acked by a GAP ACK? */
__u8
fast_retransmit
;
/* Is this chunk fast retransmitted? */
__u8
tsn_missing_report
;
/* Data chunk missing counter. */
/* What is the origin IP address for this chunk? */
union
sctp_addr
source
;
/* Destination address for this chunk. */
...
...
@@ -570,6 +565,18 @@ struct sctp_chunk {
* go. It is NULL if we have no preference.
*/
struct
sctp_transport
*
transport
;
__u8
rtt_in_progress
;
/* Is this chunk used for RTT calculation? */
__u8
resent
;
/* Has this chunk ever been retransmitted. */
__u8
has_tsn
;
/* Does this chunk have a TSN yet? */
__u8
has_ssn
;
/* Does this chunk have a SSN yet? */
__u8
singleton
;
/* Was this the only chunk in the packet? */
__u8
end_of_packet
;
/* Was this the last chunk in the packet? */
__u8
ecn_ce_done
;
/* Have we processed the ECN CE bit? */
__u8
pdiscard
;
/* Discard the whole packet now? */
__u8
tsn_gap_acked
;
/* Is this chunk acked by a GAP ACK? */
__u8
fast_retransmit
;
/* Is this chunk fast retransmitted? */
__u8
tsn_missing_report
;
/* Data chunk missing counter. */
};
void
sctp_chunk_hold
(
struct
sctp_chunk
*
);
...
...
net/sctp/chunk.c
View file @
0c336e6d
...
...
@@ -55,8 +55,8 @@ void sctp_datamsg_init(struct sctp_datamsg *msg)
atomic_set
(
&
msg
->
refcnt
,
1
);
msg
->
send_failed
=
0
;
msg
->
send_error
=
0
;
msg
->
can_expire
=
0
;
INIT_LIST_HEAD
(
&
msg
->
chunks
);
INIT_LIST_HEAD
(
&
msg
->
track
);
}
/* Allocate and initialize datamsg. */
...
...
@@ -84,7 +84,7 @@ static void sctp_datamsg_destroy(struct sctp_datamsg *msg)
notify
=
msg
->
send_failed
?
-
1
:
0
;
/* Release all references. */
list_for_each_safe
(
pos
,
temp
,
&
msg
->
track
)
{
list_for_each_safe
(
pos
,
temp
,
&
msg
->
chunks
)
{
list_del
(
pos
);
chunk
=
list_entry
(
pos
,
struct
sctp_chunk
,
frag_list
);
/* Check whether we _really_ need to notify. */
...
...
@@ -146,7 +146,6 @@ void sctp_datamsg_free(struct sctp_datamsg *msg)
void
sctp_datamsg_track
(
struct
sctp_chunk
*
chunk
)
{
sctp_chunk_hold
(
chunk
);
list_add_tail
(
&
chunk
->
frag_list
,
&
chunk
->
msg
->
track
);
}
/* Assign a chunk to this datamsg. */
...
...
@@ -179,6 +178,20 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
if
(
!
msg
)
return
NULL
;
/* Note: Calculate this outside of the loop, so that all fragments
* have the same expiration.
*/
if
(
sinfo
->
sinfo_timetolive
)
{
struct
timeval
tv
;
__u32
ttl
=
sinfo
->
sinfo_timetolive
;
/* sinfo_timetolive is in milliseconds */
tv
.
tv_sec
=
ttl
/
1000
;
tv
.
tv_usec
=
ttl
%
1000
*
1000
;
msg
->
expires_at
=
jiffies
+
timeval_to_jiffies
(
&
tv
);
msg
->
can_expire
=
1
;
}
/* What is a reasonable fragmentation point right now? */
max
=
asoc
->
pmtu
;
if
(
max
<
SCTP_MIN_PMTU
)
...
...
@@ -191,7 +204,6 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
/* Subtract out the overhead of a data chunk header. */
max
-=
sizeof
(
struct
sctp_data_chunk
);
whole
=
0
;
/* If user has specified smaller fragmentation, make it so. */
...
...
@@ -289,3 +301,27 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc,
sctp_datamsg_free
(
msg
);
return
NULL
;
}
/* Check whether this message has expired. */
int
sctp_datamsg_expires
(
struct
sctp_chunk
*
chunk
)
{
struct
sctp_datamsg
*
msg
=
chunk
->
msg
;
/* FIXME: When PR-SCTP is supported we can make this
* check more lenient.
*/
if
(
!
msg
->
can_expire
)
return
0
;
if
(
time_after
(
jiffies
,
msg
->
expires_at
))
return
1
;
return
0
;
}
/* This chunk (and consequently entire message) has failed in its sending. */
void
sctp_datamsg_fail
(
struct
sctp_chunk
*
chunk
,
int
error
)
{
chunk
->
msg
->
send_failed
=
1
;
chunk
->
msg
->
send_error
=
error
;
}
net/sctp/output.c
View file @
0c336e6d
...
...
@@ -356,6 +356,7 @@ int sctp_packet_transmit(struct sctp_packet *packet)
if
(
sctp_chunk_is_data
(
chunk
))
{
if
(
!
chunk
->
has_tsn
)
{
sctp_chunk_assign_ssn
(
chunk
);
sctp_chunk_assign_tsn
(
chunk
);
/* 6.3.1 C4) When data is in flight and when allowed
...
...
@@ -627,6 +628,8 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
rwnd
=
0
;
asoc
->
peer
.
rwnd
=
rwnd
;
/* Has been accepted for transmission. */
chunk
->
msg
->
can_expire
=
0
;
finish:
return
retval
;
...
...
net/sctp/outqueue.c
View file @
0c336e6d
...
...
@@ -251,8 +251,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
/* Mark as part of a failed message. */
chunk
->
msg
->
send_failed
=
1
;
/* Generate a SEND FAILED event. */
sctp_datamsg_fail
(
chunk
,
q
->
error
);
sctp_chunk_free
(
chunk
);
}
}
...
...
@@ -262,6 +261,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
list_del
(
lchunk
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
sctp_datamsg_fail
(
chunk
,
q
->
error
);
sctp_chunk_free
(
chunk
);
}
...
...
@@ -270,6 +270,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
list_del
(
lchunk
);
chunk
=
list_entry
(
lchunk
,
struct
sctp_chunk
,
transmitted_list
);
sctp_datamsg_fail
(
chunk
,
q
->
error
);
sctp_chunk_free
(
chunk
);
}
...
...
@@ -277,7 +278,7 @@ void sctp_outq_teardown(struct sctp_outq *q)
while
((
chunk
=
sctp_outq_dequeue_data
(
q
)))
{
/* Mark as send failure. */
chunk
->
msg
->
send_failed
=
1
;
sctp_datamsg_fail
(
chunk
,
q
->
error
)
;
sctp_chunk_free
(
chunk
);
}
...
...
@@ -800,27 +801,25 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
*/
if
(
chunk
->
sinfo
.
sinfo_stream
>=
asoc
->
c
.
sinit_num_ostreams
)
{
/* Mark as failed send. */
chunk
->
msg
->
send_failed
=
1
;
chunk
->
msg
->
send_error
=
SCTP_ERROR_INV_STRM
;
/* Free the chunk. */
/* Mark as s failed send. */
sctp_datamsg_fail
(
chunk
,
SCTP_ERROR_INV_STRM
);
sctp_chunk_free
(
chunk
);
continue
;
}
/* Now do delayed assignment of SSN. This will
* probably change again when we start supporting
* large (> approximately 2^16) size messages.
*/
sctp_chunk_assign_ssn
(
chunk
);
/* Has this chunk expired? */
if
(
sctp_datamsg_expires
(
chunk
))
{
sctp_datamsg_fail
(
chunk
,
0
);
sctp_chunk_free
(
chunk
);
continue
;
}
/* If there is a specified transport, use it.
* Otherwise, we want to use the active path.
*/
new_transport
=
chunk
->
transport
;
if
(
new_transport
==
NULL
||
!
new_transport
->
active
)
if
(
!
new_transport
||
!
new_transport
->
active
)
new_transport
=
asoc
->
peer
.
active_path
;
/* Change packets if necessary. */
...
...
net/sctp/sm_make_chunk.c
View file @
0c336e6d
...
...
@@ -992,7 +992,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
retval
->
has_tsn
=
0
;
retval
->
has_ssn
=
0
;
retval
->
rtt_in_progress
=
0
;
retval
->
sent_at
=
jiffies
;
retval
->
sent_at
=
0
;
retval
->
singleton
=
1
;
retval
->
end_of_packet
=
0
;
retval
->
ecn_ce_done
=
0
;
...
...
net/sctp/sm_statefuns.c
View file @
0c336e6d
...
...
@@ -2372,7 +2372,8 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
* PMTU. In cases, such as loopback, this might be a rather
* large spill over.
*/
if
(
asoc
->
rwnd_over
||
(
datalen
>
asoc
->
rwnd
+
asoc
->
frag_point
))
{
if
(
!
asoc
->
rwnd
||
asoc
->
rwnd_over
||
(
datalen
>
asoc
->
rwnd
+
asoc
->
frag_point
))
{
/* If this is the next TSN, consider reneging to make
* room. Note: Playing nice with a confused sender. A
...
...
net/sctp/socket.c
View file @
0c336e6d
...
...
@@ -826,7 +826,7 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
long
timeo
;
__u16
sinfo_flags
=
0
;
struct
sctp_datamsg
*
datamsg
;
struct
list_head
*
pos
,
*
temp
;
struct
list_head
*
pos
;
int
msg_flags
=
msg
->
msg_flags
;
SCTP_DEBUG_PRINTK
(
"sctp_sendmsg(sk: %p, msg: %p, msg_len: %d)
\n
"
,
...
...
@@ -1133,9 +1133,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
}
/* Now send the (possibly) fragmented message. */
list_for_each
_safe
(
pos
,
temp
,
&
datamsg
->
chunks
)
{
list_for_each
(
pos
,
&
datamsg
->
chunks
)
{
chunk
=
list_entry
(
pos
,
struct
sctp_chunk
,
frag_list
);
list_del_init
(
pos
);
sctp_datamsg_track
(
chunk
);
/* Do accounting for the write space. */
...
...
@@ -1143,7 +1142,11 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
chunk
->
transport
=
chunk_tp
;
/* Send it to the lower layers. */
/* Send it to the lower layers. Note: all chunks
* must either fail or succeed. The lower layer
* works that way today. Keep it that way or this
* breaks.
*/
err
=
sctp_primitive_SEND
(
asoc
,
chunk
);
/* Did the lower layer accept the chunk? */
if
(
err
)
...
...
net/sctp/ulpevent.c
View file @
0c336e6d
...
...
@@ -425,6 +425,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
struct
sctp_send_failed
*
ssf
;
struct
sk_buff
*
skb
;
/* Pull off any padding. */
int
len
=
ntohs
(
chunk
->
chunk_hdr
->
length
);
/* Make skb with more room so we can prepend notification. */
skb
=
skb_copy_expand
(
chunk
->
skb
,
sizeof
(
struct
sctp_send_failed
),
/* headroom */
...
...
@@ -434,7 +437,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
goto
fail
;
/* Pull off the common chunk header and DATA header. */
skb_pull
(
skb
,
sizeof
(
sctp_data_chunk_t
));
skb_pull
(
skb
,
sizeof
(
struct
sctp_data_chunk
));
len
-=
sizeof
(
struct
sctp_data_chunk
);
/* Embed the event fields inside the cloned skb. */
event
=
sctp_skb2event
(
skb
);
...
...
@@ -475,7 +479,8 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
* This field is the total length of the notification data, including
* the notification header.
*/
ssf
->
ssf_length
=
skb
->
len
;
ssf
->
ssf_length
=
sizeof
(
struct
sctp_send_failed
)
+
len
;
skb_trim
(
skb
,
ssf
->
ssf_length
);
/* Socket Extensions for SCTP
* 5.3.1.4 SCTP_SEND_FAILED
...
...
@@ -496,6 +501,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_send_failed(
*/
memcpy
(
&
ssf
->
ssf_info
,
&
chunk
->
sinfo
,
sizeof
(
struct
sctp_sndrcvinfo
));
/* Per TSVWG discussion with Randy. Allow the application to
* ressemble a fragmented message.
*/
ssf
->
ssf_info
.
sinfo_flags
=
chunk
->
chunk_hdr
->
flags
;
/* Socket Extensions for SCTP
* 5.3.1.4 SCTP_SEND_FAILED
*
...
...
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