155682Smarkm/*
2233294Sstas * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska H��gskolan
355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden).
455682Smarkm * All rights reserved.
5233294Sstas *
655682Smarkm * Redistribution and use in source and binary forms, with or without
755682Smarkm * modification, are permitted provided that the following conditions
855682Smarkm * are met:
9233294Sstas *
1055682Smarkm * 1. Redistributions of source code must retain the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer.
12233294Sstas *
1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1455682Smarkm *    notice, this list of conditions and the following disclaimer in the
1555682Smarkm *    documentation and/or other materials provided with the distribution.
16233294Sstas *
1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
20233294Sstas *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include <config.h>
3555682Smarkm
3655682Smarkm#include "roken.h"
3755682Smarkm
38233294Sstas#ifndef _WIN32
39233294Sstas
40233294SstasROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
41233294Sstassendmsg(rk_socket_t s, const struct msghdr *msg, int flags)
4255682Smarkm{
4355682Smarkm    ssize_t ret;
4455682Smarkm    size_t tot = 0;
4555682Smarkm    int i;
4655682Smarkm    char *buf, *p;
4755682Smarkm    struct iovec *iov = msg->msg_iov;
4855682Smarkm
4955682Smarkm    for(i = 0; i < msg->msg_iovlen; ++i)
5055682Smarkm	tot += iov[i].iov_len;
5155682Smarkm    buf = malloc(tot);
5255682Smarkm    if (tot != 0 && buf == NULL) {
5355682Smarkm	errno = ENOMEM;
5455682Smarkm	return -1;
5555682Smarkm    }
5655682Smarkm    p = buf;
5755682Smarkm    for (i = 0; i < msg->msg_iovlen; ++i) {
5855682Smarkm	memcpy (p, iov[i].iov_base, iov[i].iov_len);
5955682Smarkm	p += iov[i].iov_len;
6055682Smarkm    }
6155682Smarkm    ret = sendto (s, buf, tot, flags, msg->msg_name, msg->msg_namelen);
6255682Smarkm    free (buf);
6355682Smarkm    return ret;
6455682Smarkm}
65233294Sstas
66233294Sstas#else /* _WIN32 */
67233294Sstas
68233294Sstas/***********************************************************************
69233294Sstas * Copyright (c) 2009, Secure Endpoints Inc.
70233294Sstas * All rights reserved.
71233294Sstas *
72233294Sstas * Redistribution and use in source and binary forms, with or without
73233294Sstas * modification, are permitted provided that the following conditions
74233294Sstas * are met:
75233294Sstas *
76233294Sstas * - Redistributions of source code must retain the above copyright
77233294Sstas *   notice, this list of conditions and the following disclaimer.
78233294Sstas *
79233294Sstas * - Redistributions in binary form must reproduce the above copyright
80233294Sstas *   notice, this list of conditions and the following disclaimer in
81233294Sstas *   the documentation and/or other materials provided with the
82233294Sstas *   distribution.
83233294Sstas *
84233294Sstas * - Neither the name of Secure Endpoints Inc. nor the names of its
85233294Sstas *   contributors may be used to endorse or promote products derived
86233294Sstas *   from this software without specific prior written permission.
87233294Sstas *
88233294Sstas * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
89233294Sstas * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
90233294Sstas * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
91233294Sstas * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
92233294Sstas * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
93233294Sstas * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
94233294Sstas * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
95233294Sstas * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
96233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
97233294Sstas * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
98233294Sstas * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
99233294Sstas * OF THE POSSIBILITY OF SUCH DAMAGE.
100233294Sstas *
101233294Sstas **********************************************************************/
102233294Sstas
103233294Sstas/**
104233294Sstas * Implementation of sendmsg() for WIN32
105233294Sstas *
106233294Sstas * We are using a contrived definition of msghdr which actually uses
107233294Sstas * an array of ::_WSABUF structures instead of ::iovec .  This allows
108233294Sstas * us to call WSASend directly using the given ::msghdr instead of
109233294Sstas * having to allocate another array of ::_WSABUF and copying data for
110233294Sstas * each call.
111233294Sstas *
112233294Sstas * Limitations:
113233294Sstas *
114233294Sstas * - msg->msg_name is ignored.  So is msg->control.
115233294Sstas * - WSASend() only supports ::MSG_DONTROUTE, ::MSG_OOB and
116233294Sstas *   ::MSG_PARTIAL.
117233294Sstas *
118233294Sstas * @param[in] s The socket to use.
119233294Sstas * @param[in] msg The message
120233294Sstas * @param[in] flags Flags.  A combination of ::MSG_DONTROUTE,
121233294Sstas *  ::MSG_OOB and ::MSG_PARTIAL
122233294Sstas *
123233294Sstas * @return The number of bytes sent, on success.  Or -1 on error.
124233294Sstas */
125233294SstasROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
126233294Sstassendmsg_w32(rk_socket_t s, const struct msghdr * msg, int flags)
127233294Sstas{
128233294Sstas    int srv;
129233294Sstas    DWORD num_bytes_sent = 0;
130233294Sstas
131233294Sstas    /* TODO: For _WIN32_WINNT >= 0x0600 we can use WSASendMsg using
132233294Sstas       WSAMSG which is a much more direct analogue to sendmsg(). */
133233294Sstas
134233294Sstas    srv = WSASend(s, msg->msg_iov, msg->msg_iovlen,
135233294Sstas		  &num_bytes_sent, flags, NULL, NULL);
136233294Sstas
137233294Sstas    if (srv == 0)
138233294Sstas	return (int) num_bytes_sent;
139233294Sstas
140233294Sstas    /* srv == SOCKET_ERROR and WSAGetLastError() == WSA_IO_PENDING
141233294Sstas       indicates that a non-blocking transfer has been scheduled.
142233294Sstas       We'll have to check for that if we ever support non-blocking
143233294Sstas       I/O. */
144233294Sstas
145233294Sstas    return -1;
146233294Sstas}
147233294Sstas
148233294Sstas#endif /* !_WIN32 */
149