| 233 | } |
| 234 | |
| 235 | TUdpSocket::ESendError TUdpSocket::SendTo(const char* buf, size_t size, const TSockAddrPair& addr, ui8 tos, const EFragFlag frag) { |
| 236 | Y_ASSERT(IsPacketsQueueEmpty()); |
| 237 | Y_ASSERT(UDP_LOW_LEVEL_HEADER_SIZE <= size && size <= UDP_MAX_PACKET_SIZE); |
| 238 | //fprintf(stderr, "SendTo: %s -> %s\n", GetAddressAsString(GetUdpAddress(addr.RemoteAddr)).c_str(), GetAddressAsString(GetUdpAddress(addr.MyAddr)).c_str()); |
| 239 | |
| 240 | WritePacketHeader((char*)buf, size, addr.RemoteAddr); |
| 241 | |
| 242 | #ifdef SIMULATE_NETWORK_FAILURES |
| 243 | if ((RandomNumber<size_t>() % 3) == 0) |
| 244 | return SEND_OK; // packet lost |
| 245 | if ((RandomNumber<size_t>() % 3) == 0) |
| 246 | (char&)(buf[RandomNumber<size_t>() % size]) += RandomNumber<size_t>(); // packet broken |
| 247 | #endif |
| 248 | |
| 249 | char controllBuffer[CTRL_BUFFER_SIZE]; |
| 250 | const TIoVec iov = CreateIoVec((char*)buf, size); // store as local variable on the stack |
| 251 | |
| 252 | const TMsgHdr hdr = CreateNl12SendMsgHdr(addr.RemoteAddr, addr.MyAddr, iov, tos, controllBuffer, CTRL_BUFFER_SIZE); |
| 253 | const int rv = S->SendMsg(&hdr, 0, frag); |
| 254 | if (rv < 0) |
| 255 | return GetSendErrorFromErrno(LastSystemError()); |
| 256 | |
| 257 | Y_ASSERT((size_t)rv == size); |
| 258 | return SEND_OK; |
| 259 | } |
| 260 | |
| 261 | /////////////////////////////////////////////////////////////////////////////// |
| 262 | |