Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(201)

Side by Side Diff: talk/media/sctp/sctpdataengine.cc

Issue 1315923003: Revert of Added send-thresholding and fixed text packet dumping. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « talk/media/sctp/sctpdataengine.h ('k') | talk/media/sctp/sctpdataengine_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2012 Google Inc. and Robin Seggelmann 3 * Copyright 2012 Google Inc. and Robin Seggelmann
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 } // namespace 102 } // namespace
103 103
104 namespace cricket { 104 namespace cricket {
105 typedef rtc::ScopedMessageData<SctpInboundPacket> InboundPacketMessage; 105 typedef rtc::ScopedMessageData<SctpInboundPacket> InboundPacketMessage;
106 typedef rtc::ScopedMessageData<rtc::Buffer> OutboundPacketMessage; 106 typedef rtc::ScopedMessageData<rtc::Buffer> OutboundPacketMessage;
107 107
108 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280, 108 // The biggest SCTP packet. Starting from a 'safe' wire MTU value of 1280,
109 // take off 80 bytes for DTLS/TURN/TCP/IP overhead. 109 // take off 80 bytes for DTLS/TURN/TCP/IP overhead.
110 static const size_t kSctpMtu = 1200; 110 static const size_t kSctpMtu = 1200;
111 111
112 // The size of the SCTP association send buffer. 256kB, the usrsctp default.
113 static const int kSendBufferSize = 262144;
114 enum { 112 enum {
115 MSG_SCTPINBOUNDPACKET = 1, // MessageData is SctpInboundPacket 113 MSG_SCTPINBOUNDPACKET = 1, // MessageData is SctpInboundPacket
116 MSG_SCTPOUTBOUNDPACKET = 2, // MessageData is rtc:Buffer 114 MSG_SCTPOUTBOUNDPACKET = 2, // MessageData is rtc:Buffer
117 }; 115 };
118 116
119 struct SctpInboundPacket { 117 struct SctpInboundPacket {
120 rtc::Buffer buffer; 118 rtc::Buffer buffer;
121 ReceiveDataParams params; 119 ReceiveDataParams params;
122 // The |flags| parameter is used by SCTP to distinguish notification packets 120 // The |flags| parameter is used by SCTP to distinguish notification packets
123 // from other types of packets. 121 // from other types of packets.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 case SctpDataMediaChannel::PPID_NONE: 170 case SctpDataMediaChannel::PPID_NONE:
173 *dest = cricket::DMT_NONE; 171 *dest = cricket::DMT_NONE;
174 return true; 172 return true;
175 173
176 default: 174 default:
177 return false; 175 return false;
178 } 176 }
179 } 177 }
180 178
181 // Log the packet in text2pcap format, if log level is at LS_VERBOSE. 179 // Log the packet in text2pcap format, if log level is at LS_VERBOSE.
182 static void VerboseLogPacket(void *data, size_t length, int direction) { 180 static void VerboseLogPacket(void *addr, size_t length, int direction) {
183 if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) { 181 if (LOG_CHECK_LEVEL(LS_VERBOSE) && length > 0) {
184 char *dump_buf; 182 char *dump_buf;
185 if ((dump_buf = usrsctp_dumppacket( 183 if ((dump_buf = usrsctp_dumppacket(
186 data, length, direction)) != NULL) { 184 addr, length, direction)) != NULL) {
187 LOG(LS_VERBOSE) << dump_buf; 185 LOG(LS_VERBOSE) << dump_buf;
188 usrsctp_freedumpbuffer(dump_buf); 186 usrsctp_freedumpbuffer(dump_buf);
189 } 187 }
190 } 188 }
191 } 189 }
192 190
193 // This is the callback usrsctp uses when there's data to send on the network 191 // This is the callback usrsctp uses when there's data to send on the network
194 // that has been wrapped appropriatly for the SCTP protocol. 192 // that has been wrapped appropriatly for the SCTP protocol.
195 static int OnSctpOutboundPacket(void* addr, void* data, size_t length, 193 static int OnSctpOutboundPacket(void* addr, void* data, size_t length,
196 uint8_t tos, uint8_t set_df) { 194 uint8_t tos, uint8_t set_df) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 // The ownership of |packet| transfers to |msg|. 237 // The ownership of |packet| transfers to |msg|.
240 InboundPacketMessage* msg = new InboundPacketMessage(packet); 238 InboundPacketMessage* msg = new InboundPacketMessage(packet);
241 channel->worker_thread()->Post(channel, MSG_SCTPINBOUNDPACKET, msg); 239 channel->worker_thread()->Post(channel, MSG_SCTPINBOUNDPACKET, msg);
242 } 240 }
243 free(data); 241 free(data);
244 return 1; 242 return 1;
245 } 243 }
246 244
247 // Set the initial value of the static SCTP Data Engines reference count. 245 // Set the initial value of the static SCTP Data Engines reference count.
248 int SctpDataEngine::usrsctp_engines_count = 0; 246 int SctpDataEngine::usrsctp_engines_count = 0;
249 // All the channels created by this engine, used for callbacks from
250 // usrsctplib that only contain socket pointers. Channels are removed when
251 // SignalDestroyed is fired.
252 std::vector<SctpDataMediaChannel*> SctpDataEngine::channels_;
253 247
254 SctpDataEngine::SctpDataEngine() { 248 SctpDataEngine::SctpDataEngine() {
255 if (usrsctp_engines_count == 0) { 249 if (usrsctp_engines_count == 0) {
256 // First argument is udp_encapsulation_port, which is not releveant for our 250 // First argument is udp_encapsulation_port, which is not releveant for our
257 // AF_CONN use of sctp. 251 // AF_CONN use of sctp.
258 usrsctp_init(0, cricket::OnSctpOutboundPacket, debug_sctp_printf); 252 usrsctp_init(0, cricket::OnSctpOutboundPacket, debug_sctp_printf);
259 253
260 // To turn on/off detailed SCTP debugging. You will also need to have the 254 // To turn on/off detailed SCTP debugging. You will also need to have the
261 // SCTP_DEBUG cpp defines flag. 255 // SCTP_DEBUG cpp defines flag.
262 // usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL); 256 // usrsctp_sysctl_set_sctp_debug_on(SCTP_DEBUG_ALL);
263 257
264 // TODO(ldixon): Consider turning this on/off. 258 // TODO(ldixon): Consider turning this on/off.
265 usrsctp_sysctl_set_sctp_ecn_enable(0); 259 usrsctp_sysctl_set_sctp_ecn_enable(0);
266 260
267 int send_size = usrsctp_sysctl_get_sctp_sendspace();
268 if (send_size != kSendBufferSize) {
269 LOG(LS_ERROR) << "Got different send size than expected: " << send_size;
270 }
271
272 // TODO(ldixon): Consider turning this on/off. 261 // TODO(ldixon): Consider turning this on/off.
273 // This is not needed right now (we don't do dynamic address changes): 262 // This is not needed right now (we don't do dynamic address changes):
274 // If SCTP Auto-ASCONF is enabled, the peer is informed automatically 263 // If SCTP Auto-ASCONF is enabled, the peer is informed automatically
275 // when a new address is added or removed. This feature is enabled by 264 // when a new address is added or removed. This feature is enabled by
276 // default. 265 // default.
277 // usrsctp_sysctl_set_sctp_auto_asconf(0); 266 // usrsctp_sysctl_set_sctp_auto_asconf(0);
278 267
279 // TODO(ldixon): Consider turning this on/off. 268 // TODO(ldixon): Consider turning this on/off.
280 // Add a blackhole sysctl. Setting it to 1 results in no ABORTs 269 // Add a blackhole sysctl. Setting it to 1 results in no ABORTs
281 // being sent in response to INITs, setting it to 2 results 270 // being sent in response to INITs, setting it to 2 results
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 305 }
317 LOG(LS_ERROR) << "Failed to shutdown usrsctp."; 306 LOG(LS_ERROR) << "Failed to shutdown usrsctp.";
318 } 307 }
319 } 308 }
320 309
321 DataMediaChannel* SctpDataEngine::CreateChannel( 310 DataMediaChannel* SctpDataEngine::CreateChannel(
322 DataChannelType data_channel_type) { 311 DataChannelType data_channel_type) {
323 if (data_channel_type != DCT_SCTP) { 312 if (data_channel_type != DCT_SCTP) {
324 return NULL; 313 return NULL;
325 } 314 }
326 SctpDataMediaChannel *channel = new SctpDataMediaChannel( 315 return new SctpDataMediaChannel(rtc::Thread::Current());
327 rtc::Thread::Current());
328 channels_.push_back(channel);
329 channel->SignalDestroyed.connect(this, &SctpDataEngine::OnChannelDestroyed);
330 return channel;
331 } 316 }
332 317
333 // static
334 SctpDataMediaChannel* SctpDataEngine::GetChannelFromSocket(
335 struct socket* sock) {
336 for (auto p:channels_) {
337 if (p->socket() == sock) {
338 return p;
339 }
340 }
341 return 0;
342 }
343
344
345 void SctpDataEngine::OnChannelDestroyed(SctpDataMediaChannel* channel) {
346 auto it = std::find(channels_.begin(), channels_.end(), channel);
347 if (it == channels_.end()) {
348 LOG(LS_ERROR) << "OnChannelDestroyed: the channel wasn't registered.";
349 return;
350 }
351 channels_.erase(it);
352 }
353
354 // static
355 int SctpDataEngine::SendThresholdCallback(struct socket* sock,
356 uint32_t sb_free) {
357 SctpDataMediaChannel *channel = GetChannelFromSocket(sock);
358 if (!channel) {
359 LOG(LS_ERROR) << "SendThresholdCallback: Failed to get channel for socket "
360 << sock;
361 return 0;
362 }
363 channel->SignalReadyToSend(true);
364 return 0;
365 }
366
367
368 SctpDataMediaChannel::SctpDataMediaChannel(rtc::Thread* thread) 318 SctpDataMediaChannel::SctpDataMediaChannel(rtc::Thread* thread)
369 : worker_thread_(thread), 319 : worker_thread_(thread),
370 local_port_(kSctpDefaultPort), 320 local_port_(kSctpDefaultPort),
371 remote_port_(kSctpDefaultPort), 321 remote_port_(kSctpDefaultPort),
372 sock_(NULL), 322 sock_(NULL),
373 sending_(false), 323 sending_(false),
374 receiving_(false), 324 receiving_(false),
375 debug_name_("SctpDataMediaChannel") { 325 debug_name_("SctpDataMediaChannel") {
376 } 326 }
377 327
378 SctpDataMediaChannel::~SctpDataMediaChannel() { 328 SctpDataMediaChannel::~SctpDataMediaChannel() {
379 CloseSctpSocket(); 329 CloseSctpSocket();
380 SignalDestroyed(this);
381 } 330 }
382 331
383 sockaddr_conn SctpDataMediaChannel::GetSctpSockAddr(int port) { 332 sockaddr_conn SctpDataMediaChannel::GetSctpSockAddr(int port) {
384 sockaddr_conn sconn = {0}; 333 sockaddr_conn sconn = {0};
385 sconn.sconn_family = AF_CONN; 334 sconn.sconn_family = AF_CONN;
386 #ifdef HAVE_SCONN_LEN 335 #ifdef HAVE_SCONN_LEN
387 sconn.sconn_len = sizeof(sockaddr_conn); 336 sconn.sconn_len = sizeof(sockaddr_conn);
388 #endif 337 #endif
389 // Note: conversion from int to uint16_t happens here. 338 // Note: conversion from int to uint16_t happens here.
390 sconn.sconn_port = rtc::HostToNetwork16(port); 339 sconn.sconn_port = rtc::HostToNetwork16(port);
391 sconn.sconn_addr = this; 340 sconn.sconn_addr = this;
392 return sconn; 341 return sconn;
393 } 342 }
394 343
395 bool SctpDataMediaChannel::OpenSctpSocket() { 344 bool SctpDataMediaChannel::OpenSctpSocket() {
396 if (sock_) { 345 if (sock_) {
397 LOG(LS_VERBOSE) << debug_name_ 346 LOG(LS_VERBOSE) << debug_name_
398 << "->Ignoring attempt to re-create existing socket."; 347 << "->Ignoring attempt to re-create existing socket.";
399 return false; 348 return false;
400 } 349 }
401
402 // If kSendBufferSize isn't reflective of reality, we log an error, but we
403 // still have to do something reasonable here. Look up what the buffer's
404 // real size is and set our threshold to something reasonable.
405 const static int send_threshold = usrsctp_sysctl_get_sctp_sendspace() / 2;
406
407 sock_ = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, 350 sock_ = usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP,
408 cricket::OnSctpInboundPacket, 351 cricket::OnSctpInboundPacket, NULL, 0, this);
409 &SctpDataEngine::SendThresholdCallback,
410 send_threshold, this);
411 if (!sock_) { 352 if (!sock_) {
412 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to create SCTP socket."; 353 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to create SCTP socket.";
413 return false; 354 return false;
414 } 355 }
415 356
416 // Make the socket non-blocking. Connect, close, shutdown etc will not block 357 // Make the socket non-blocking. Connect, close, shutdown etc will not block
417 // the thread waiting for the socket operation to complete. 358 // the thread waiting for the socket operation to complete.
418 if (usrsctp_set_non_blocking(sock_, 1) < 0) { 359 if (usrsctp_set_non_blocking(sock_, 1) < 0) {
419 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP to non blocking."; 360 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP to non blocking.";
420 return false; 361 return false;
(...skipping 24 matching lines...) Expand all
445 386
446 // Nagle. 387 // Nagle.
447 uint32_t nodelay = 1; 388 uint32_t nodelay = 1;
448 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_NODELAY, &nodelay, 389 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_NODELAY, &nodelay,
449 sizeof(nodelay))) { 390 sizeof(nodelay))) {
450 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP_NODELAY."; 391 LOG_ERRNO(LS_ERROR) << debug_name_ << "Failed to set SCTP_NODELAY.";
451 return false; 392 return false;
452 } 393 }
453 394
454 // Disable MTU discovery 395 // Disable MTU discovery
455 struct sctp_paddrparams params; 396 struct sctp_paddrparams params = {{0}};
456 memset(&params, 0, sizeof(params));
457 params.spp_assoc_id = 0; 397 params.spp_assoc_id = 0;
458 params.spp_flags = SPP_PMTUD_DISABLE; 398 params.spp_flags = SPP_PMTUD_DISABLE;
459 params.spp_pathmtu = kSctpMtu; 399 params.spp_pathmtu = kSctpMtu;
460 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &params, 400 if (usrsctp_setsockopt(sock_, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, &params,
461 sizeof(params))) { 401 sizeof(params))) {
462 LOG_ERRNO(LS_ERROR) << debug_name_ 402 LOG_ERRNO(LS_ERROR) << debug_name_
463 << "Failed to set SCTP_PEER_ADDR_PARAMS."; 403 << "Failed to set SCTP_PEER_ADDR_PARAMS.";
464 return false; 404 return false;
465 } 405 }
466 406
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 } 897 }
958 898
959 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) { 899 bool SctpDataMediaChannel::SetRecvCodecs(const std::vector<DataCodec>& codecs) {
960 return GetCodecIntParameter( 900 return GetCodecIntParameter(
961 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort, 901 codecs, kGoogleSctpDataCodecId, kGoogleSctpDataCodecName, kCodecParamPort,
962 &local_port_); 902 &local_port_);
963 } 903 }
964 904
965 void SctpDataMediaChannel::OnPacketFromSctpToNetwork( 905 void SctpDataMediaChannel::OnPacketFromSctpToNetwork(
966 rtc::Buffer* buffer) { 906 rtc::Buffer* buffer) {
967 // usrsctp seems to interpret the MTU we give it strangely -- it seems to 907 if (buffer->size() > kSctpMtu) {
968 // give us back packets bigger than that MTU, if only by a fixed amount.
969 // This is that amount that we've observed.
970 const int kSctpOverhead = 76;
971 if (buffer->size() > (kSctpOverhead + kSctpMtu)) {
972 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): " 908 LOG(LS_ERROR) << debug_name_ << "->OnPacketFromSctpToNetwork(...): "
973 << "SCTP seems to have made a packet that is bigger " 909 << "SCTP seems to have made a packet that is bigger "
974 << "than its official MTU: " << buffer->size() 910 "than its official MTU.";
975 << " vs max of " << kSctpMtu
976 << " even after adding " << kSctpOverhead
977 << " extra SCTP overhead";
978 } 911 }
979 MediaChannel::SendPacket(buffer); 912 MediaChannel::SendPacket(buffer);
980 } 913 }
981 914
982 bool SctpDataMediaChannel::SendQueuedStreamResets() { 915 bool SctpDataMediaChannel::SendQueuedStreamResets() {
983 if (!sent_reset_streams_.empty() || queued_reset_streams_.empty()) 916 if (!sent_reset_streams_.empty() || queued_reset_streams_.empty())
984 return true; 917 return true;
985 918
986 LOG(LS_VERBOSE) << "SendQueuedStreamResets[" << debug_name_ << "]: Sending [" 919 LOG(LS_VERBOSE) << "SendQueuedStreamResets[" << debug_name_ << "]: Sending ["
987 << ListStreams(queued_reset_streams_) << "], Open: [" 920 << ListStreams(queued_reset_streams_) << "], Open: ["
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 } 962 }
1030 case MSG_SCTPOUTBOUNDPACKET: { 963 case MSG_SCTPOUTBOUNDPACKET: {
1031 rtc::scoped_ptr<OutboundPacketMessage> pdata( 964 rtc::scoped_ptr<OutboundPacketMessage> pdata(
1032 static_cast<OutboundPacketMessage*>(msg->pdata)); 965 static_cast<OutboundPacketMessage*>(msg->pdata));
1033 OnPacketFromSctpToNetwork(pdata->data().get()); 966 OnPacketFromSctpToNetwork(pdata->data().get());
1034 break; 967 break;
1035 } 968 }
1036 } 969 }
1037 } 970 }
1038 } // namespace cricket 971 } // namespace cricket
OLDNEW
« no previous file with comments | « talk/media/sctp/sctpdataengine.h ('k') | talk/media/sctp/sctpdataengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698