| 354 | } |
| 355 | |
| 356 | ssize_t TAbstractSocket::SendMsg(const TMsgHdr* hdr, int flags, const EFragFlag frag) { |
| 357 | Y_ASSERT(IsValid()); |
| 358 | #ifdef _win32_ |
| 359 | static bool checked = 0; |
| 360 | Y_ABORT_UNLESS(hdr->msg_iov->iov_len == 1, "Scatter/gather is currenly not supported on Windows"); |
| 361 | if (hdr->Tos || frag == FF_DONT_FRAG) { |
| 362 | TWriteGuard wg(Mutex); |
| 363 | if (frag == FF_DONT_FRAG) { |
| 364 | ForbidFragmentation(); |
| 365 | } else { |
| 366 | Y_ABORT_UNLESS(checked || (checked = !IsFragmentationForbiden()), "Send methods of this class expect default EnableFragmentation behavior"); |
| 367 | } |
| 368 | int originalTos; |
| 369 | if (hdr->Tos) { |
| 370 | socklen_t sz = sizeof(originalTos); |
| 371 | Y_ABORT_UNLESS(GetSockOpt(IPPROTO_IP, IP_TOS, (char*)&originalTos, &sz) == 0, ""); |
| 372 | Y_ABORT_UNLESS(SetSockOpt(IPPROTO_IP, IP_TOS, (char*)&hdr->Tos, sizeof(hdr->Tos)) == 0, ""); |
| 373 | } |
| 374 | const ssize_t rv = sendto(S, hdr->msg_iov->iov_base, hdr->msg_iov->iov_len, flags, (sockaddr*)hdr->msg_name, hdr->msg_namelen); |
| 375 | if (hdr->Tos) { |
| 376 | Y_ABORT_UNLESS(SetSockOpt(IPPROTO_IP, IP_TOS, (char*)&originalTos, sizeof(originalTos)) == 0, ""); |
| 377 | } |
| 378 | if (frag == FF_DONT_FRAG) { |
| 379 | EnableFragmentation(); |
| 380 | } |
| 381 | return rv; |
| 382 | } |
| 383 | TReadGuard rg(Mutex); |
| 384 | Y_ABORT_UNLESS(checked || (checked = !IsFragmentationForbiden()), "Send methods of this class expect default EnableFragmentation behavior"); |
| 385 | return sendto(S, hdr->msg_iov->iov_base, hdr->msg_iov->iov_len, flags, (sockaddr*)hdr->msg_name, hdr->msg_namelen); |
| 386 | #else |
| 387 | if (frag == FF_DONT_FRAG) { |
| 388 | TWriteGuard wg(Mutex); |
| 389 | ForbidFragmentation(); |
| 390 | const ssize_t rv = sendmsg(S, hdr, flags); |
| 391 | EnableFragmentation(); |
| 392 | return rv; |
| 393 | } |
| 394 | |
| 395 | TReadGuard rg(Mutex); |
| 396 | #ifndef _darwin_ |
| 397 | static bool checked = 0; |
| 398 | Y_ABORT_UNLESS(checked || (checked = !IsFragmentationForbiden()), "Send methods of this class expect default EnableFragmentation behavior"); |
| 399 | #endif |
| 400 | return sendmsg(S, hdr, flags); |
| 401 | #endif |
| 402 | } |
| 403 | |
| 404 | bool TAbstractSocket::IncreaseSendBuff() { |
| 405 | int buffSize; |