Chromium Code Reviews| Index: talk/media/sctp/sctpdataengine.cc |
| diff --git a/talk/media/sctp/sctpdataengine.cc b/talk/media/sctp/sctpdataengine.cc |
| index 8c8a6a192fa25833c3de66c0587b9ed7ed3bccb3..26513cb49075c34ec49685b2e8e708131fec7ad9 100644 |
| --- a/talk/media/sctp/sctpdataengine.cc |
| +++ b/talk/media/sctp/sctpdataengine.cc |
| @@ -177,11 +177,11 @@ static bool GetDataMediaType( |
| } |
| // Log the packet in text2pcap format, if log level is at LS_VERBOSE. |
| -static void VerboseLogPacket(void *addr, size_t length, int direction) { |
| +static void VerboseLogPacket(void *data, size_t length, int direction) { |
| if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) { |
| char *dump_buf; |
| if ((dump_buf = usrsctp_dumppacket( |
| - addr, length, direction)) != NULL) { |
| + data, length, direction)) != NULL) { |
| LOG(LS_VERBOSE) << dump_buf; |
| usrsctp_freedumpbuffer(dump_buf); |
| } |
| @@ -198,7 +198,7 @@ static int OnSctpOutboundPacket(void* addr, void* data, size_t length, |
| << "; tos: " << std::hex << static_cast<int>(tos) |
| << "; set_df: " << std::hex << static_cast<int>(set_df); |
| - VerboseLogPacket(addr, length, SCTP_DUMP_OUTBOUND); |
| + VerboseLogPacket(data, length, SCTP_DUMP_OUTBOUND); |
| // Note: We have to copy the data; the caller will delete it. |
| auto* msg = new OutboundPacketMessage( |
| new rtc::Buffer(reinterpret_cast<uint8_t*>(data), length)); |
| @@ -315,6 +315,9 @@ DataMediaChannel* SctpDataEngine::CreateChannel( |
| return new SctpDataMediaChannel(rtc::Thread::Current()); |
| } |
| +// Our registrar of sockets to their channels. Used for callbacks. |
| +SctpDataMediaChannel::SocketChannelMap SctpDataMediaChannel::sock_channel_map_; |
| + |
| SctpDataMediaChannel::SctpDataMediaChannel(rtc::Thread* thread) |
| : worker_thread_(thread), |
| local_port_(kSctpDefaultPort), |
| @@ -341,19 +344,40 @@ sockaddr_conn SctpDataMediaChannel::GetSctpSockAddr(int port) { |
| return sconn; |
| } |
| +// static |
| +int SctpDataMediaChannel::SendThresholdCallback(struct socket* sock, |
|
pthatcher1
2015/08/05 21:42:55
I think it would make more sense to put this callb
lally1
2015/08/18 20:38:56
I don't know where I'd get an instance pointer.
pthatcher1
2015/08/18 21:51:52
The instance pointer to the engine? Could you use
|
| + uint32_t sb_free) { |
|
pthatcher1
2015/08/05 21:42:55
No ulp_info, like with reading a packet? That's l
lally1
2015/08/18 20:38:56
Yeah, that's the real issue here. I had a prior v
|
| + SocketChannelMap::iterator it = sock_channel_map_.find(sock); |
|
pthatcher1
2015/08/05 21:42:55
You can use
auto it = sock_channel_map_.find(soc
lally1
2015/08/18 20:38:56
Thanks!
|
| + if (it == sock_channel_map_.end()) { |
|
pthatcher1
2015/08/05 21:42:55
Since there are almost always a very low number of
lally1
2015/08/18 20:38:56
Done.
|
| + // Socket is in the process of shutdown. |
| + LOG(LS_ERROR) << "Failed to get SctpDataMediaChannel for socket " << sock; |
| + return 0; |
| + } |
| + |
| + it->second->SignalReadyToSend(true); |
| + return 0; |
| +} |
| + |
| bool SctpDataMediaChannel::OpenSctpSocket() { |
| if (sock_) { |
| LOG(LS_VERBOSE) << debug_name_ |
| << "->Ignoring attempt to re-create existing socket."; |
| return false; |
| } |
| + |
| + const int send_threshold = usrsctp_sysctl_get_sctp_sendspace() / 2; |
| + |
| sock_ = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, |
| - cricket::OnSctpInboundPacket, NULL, 0, this); |
| + cricket::OnSctpInboundPacket, |
| + &SctpDataMediaChannel::SendThresholdCallback, |
| + send_threshold, this); |
| if (!sock_) { |
| LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to create SCTP socket."; |
| return false; |
| } |
| + sock_channel_map_[sock_] = this; |
| + |
| // Make the socket non-blocking. Connect, close, shutdown etc will not block |
| // the thread waiting for the socket operation to complete. |
| if (usrsctp_set_non_blocking(sock_, 1) < 0) { |
| @@ -393,7 +417,8 @@ bool SctpDataMediaChannel::OpenSctpSocket() { |
| } |
| // Disable MTU discovery |
| - struct sctp_paddrparams params = {{0}}; |
| + struct sctp_paddrparams params; |
| + memset(¶ms, 0, sizeof(params)); |
| params.spp_assoc_id = 0; |
| params.spp_flags = SPP_PMTUD_DISABLE; |
| params.spp_pathmtu = kSctpMtu; |
| @@ -437,6 +462,12 @@ void SctpDataMediaChannel::CloseSctpSocket() { |
| // close is called. This means that any pending packets in usrsctp will be |
| // discarded instead of being sent. |
| usrsctp_close(sock_); |
| + SocketChannelMap::iterator it = sock_channel_map_.find(sock_); |
| + if (it != sock_channel_map_.end()) { |
| + sock_channel_map_.erase(it); |
| + } else { |
| + LOG(LS_ERROR) << "CloseSctpSocket: the socket wasn't registered."; |
| + } |
|
pthatcher1
2015/08/05 21:42:55
I think this works, and it shorter and only does o
lally1
2015/08/18 20:38:56
Thanks. Moved above into ~SctpDataMediaChannel(),
|
| sock_ = NULL; |
| usrsctp_deregister_address(this); |
| } |
| @@ -904,10 +935,13 @@ bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { |
| void SctpDataMediaChannel::OnPacketFromSctpToNetwork( |
| rtc::Buffer* buffer) { |
| - if (buffer->size() > kSctpMtu) { |
| + // this is completely made up. |
| + const int kSctpOverhead = 76; |
|
pthatcher1
2015/08/05 21:42:55
This could use a little more documentation, even i
lally1
2015/08/18 20:38:56
Done.
|
| + if (buffer->size() > (kSctpOverhead + kSctpMtu)) { |
| LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " |
| << "SCTP seems to have made a packet that is bigger " |
| - "than its official MTU."; |
| + << "than its official MTU: " << buffer->size() |
| + << " vs max of " << kSctpMtu; |
|
pthatcher1
2015/08/05 21:42:55
Should probably include something like "assuming X
lally1
2015/08/18 20:38:56
Done.
|
| } |
| MediaChannel::SendPacket(buffer); |
| } |