329 from, err = anyToSockaddr(fd, &rsa) |
329 from, err = anyToSockaddr(fd, &rsa) |
330 } |
330 } |
331 return |
331 return |
332 } |
332 } |
333 |
333 |
|
334 // Recvmsg receives a message from a socket using the recvmsg system call. The |
|
335 // received non-control data will be written to p, and any "out of band" |
|
336 // control data will be written to oob. The flags are passed to recvmsg. |
|
337 // |
|
338 // The results are: |
|
339 // - n is the number of non-control data bytes read into p |
|
340 // - oobn is the number of control data bytes read into oob; this may be interpreted using [ParseSocketControlMessage] |
|
341 // - recvflags is flags returned by recvmsg |
|
342 // - from is the address of the sender |
|
343 // |
|
344 // If the underlying socket type is not SOCK_DGRAM, a received message |
|
345 // containing oob data and a single '\0' of non-control data is treated as if |
|
346 // the message contained only control data, i.e. n will be zero on return. |
334 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
347 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
335 var iov [1]Iovec |
348 var iov [1]Iovec |
336 if len(p) > 0 { |
349 if len(p) > 0 { |
337 iov[0].Base = &p[0] |
350 iov[0].Base = &p[0] |
338 iov[0].SetLen(len(p)) |
351 iov[0].SetLen(len(p)) |
344 from, err = anyToSockaddr(fd, &rsa) |
357 from, err = anyToSockaddr(fd, &rsa) |
345 } |
358 } |
346 return |
359 return |
347 } |
360 } |
348 |
361 |
349 // RecvmsgBuffers receives a message from a socket using the recvmsg |
362 // RecvmsgBuffers receives a message from a socket using the recvmsg system |
350 // system call. The flags are passed to recvmsg. Any non-control data |
363 // call. This function is equivalent to Recvmsg, but non-control data read is |
351 // read is scattered into the buffers slices. The results are: |
364 // scattered into the buffers slices. |
352 // - n is the number of non-control data read into bufs |
|
353 // - oobn is the number of control data read into oob; this may be interpreted using [ParseSocketControlMessage] |
|
354 // - recvflags is flags returned by recvmsg |
|
355 // - from is the address of the sender |
|
356 func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
365 func RecvmsgBuffers(fd int, buffers [][]byte, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) { |
357 iov := make([]Iovec, len(buffers)) |
366 iov := make([]Iovec, len(buffers)) |
358 for i := range buffers { |
367 for i := range buffers { |
359 if len(buffers[i]) > 0 { |
368 if len(buffers[i]) > 0 { |
360 iov[i].Base = &buffers[i][0] |
369 iov[i].Base = &buffers[i][0] |
369 from, err = anyToSockaddr(fd, &rsa) |
378 from, err = anyToSockaddr(fd, &rsa) |
370 } |
379 } |
371 return |
380 return |
372 } |
381 } |
373 |
382 |
|
383 // Sendmsg sends a message on a socket to an address using the sendmsg system |
|
384 // call. This function is equivalent to SendmsgN, but does not return the |
|
385 // number of bytes actually sent. |
374 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { |
386 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) { |
375 _, err = SendmsgN(fd, p, oob, to, flags) |
387 _, err = SendmsgN(fd, p, oob, to, flags) |
376 return |
388 return |
377 } |
389 } |
378 |
390 |
|
391 // SendmsgN sends a message on a socket to an address using the sendmsg system |
|
392 // call. p contains the non-control data to send, and oob contains the "out of |
|
393 // band" control data. The flags are passed to sendmsg. The number of |
|
394 // non-control bytes actually written to the socket is returned. |
|
395 // |
|
396 // Some socket types do not support sending control data without accompanying |
|
397 // non-control data. If p is empty, and oob contains control data, and the |
|
398 // underlying socket type is not SOCK_DGRAM, p will be treated as containing a |
|
399 // single '\0' and the return value will indicate zero bytes sent. |
|
400 // |
|
401 // The Go function Recvmsg, if called with an empty p and a non-empty oob, |
|
402 // will read and ignore this additional '\0'. If the message is received by |
|
403 // code that does not use Recvmsg, or that does not use Go at all, that code |
|
404 // will need to be written to expect and ignore the additional '\0'. |
|
405 // |
|
406 // If you need to send non-empty oob with p actually empty, and if the |
|
407 // underlying socket type supports it, you can do so via a raw system call as |
|
408 // follows: |
|
409 // |
|
410 // msg := &unix.Msghdr{ |
|
411 // Control: &oob[0], |
|
412 // } |
|
413 // msg.SetControllen(len(oob)) |
|
414 // n, _, errno := unix.Syscall(unix.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(msg)), flags) |
379 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { |
415 func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) { |
380 var iov [1]Iovec |
416 var iov [1]Iovec |
381 if len(p) > 0 { |
417 if len(p) > 0 { |
382 iov[0].Base = &p[0] |
418 iov[0].Base = &p[0] |
383 iov[0].SetLen(len(p)) |
419 iov[0].SetLen(len(p)) |
392 } |
428 } |
393 return sendmsgN(fd, iov[:], oob, ptr, salen, flags) |
429 return sendmsgN(fd, iov[:], oob, ptr, salen, flags) |
394 } |
430 } |
395 |
431 |
396 // SendmsgBuffers sends a message on a socket to an address using the sendmsg |
432 // SendmsgBuffers sends a message on a socket to an address using the sendmsg |
397 // system call. The flags are passed to sendmsg. Any non-control data written |
433 // system call. This function is equivalent to SendmsgN, but the non-control |
398 // is gathered from buffers. The function returns the number of bytes written |
434 // data is gathered from buffers. |
399 // to the socket. |
|
400 func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) { |
435 func SendmsgBuffers(fd int, buffers [][]byte, oob []byte, to Sockaddr, flags int) (n int, err error) { |
401 iov := make([]Iovec, len(buffers)) |
436 iov := make([]Iovec, len(buffers)) |
402 for i := range buffers { |
437 for i := range buffers { |
403 if len(buffers[i]) > 0 { |
438 if len(buffers[i]) > 0 { |
404 iov[i].Base = &buffers[i][0] |
439 iov[i].Base = &buffers[i][0] |
421 func Send(s int, buf []byte, flags int) (err error) { |
456 func Send(s int, buf []byte, flags int) (err error) { |
422 return sendto(s, buf, flags, nil, 0) |
457 return sendto(s, buf, flags, nil, 0) |
423 } |
458 } |
424 |
459 |
425 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { |
460 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) { |
426 ptr, n, err := to.sockaddr() |
461 var ptr unsafe.Pointer |
427 if err != nil { |
462 var salen _Socklen |
428 return err |
463 if to != nil { |
429 } |
464 ptr, salen, err = to.sockaddr() |
430 return sendto(fd, p, flags, ptr, n) |
465 if err != nil { |
|
466 return err |
|
467 } |
|
468 } |
|
469 return sendto(fd, p, flags, ptr, salen) |
431 } |
470 } |
432 |
471 |
433 func SetsockoptByte(fd, level, opt int, value byte) (err error) { |
472 func SetsockoptByte(fd, level, opt int, value byte) (err error) { |
434 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) |
473 return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1) |
435 } |
474 } |