From e64d8f1b0b3fa520ca1e9bb5994f255443222569 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 21 Apr 2017 12:37:01 +0200 Subject: [PATCH] webservices: Add support for outgoing UDP connections. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/channel.c | 63 +++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c index 162c634f568..6c4b3d0892b 100644 --- a/dlls/webservices/channel.c +++ b/dlls/webservices/channel.c @@ -108,6 +108,10 @@ struct channel { SOCKET socket; } tcp; + struct + { + SOCKET socket; + } udp; } u; char *read_buf; ULONG read_buflen; @@ -160,6 +164,11 @@ static void reset_channel( struct channel *channel ) channel->u.tcp.socket = -1; break; + case WS_UDP_CHANNEL_BINDING: + closesocket( channel->u.udp.socket ); + channel->u.udp.socket = -1; + break; + default: break; } } @@ -210,6 +219,10 @@ static HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding, channel->u.tcp.socket = -1; break; + case WS_UDP_CHANNEL_BINDING: + channel->u.udp.socket = -1; + break; + default: break; } @@ -240,7 +253,8 @@ HRESULT WINAPI WsCreateChannel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding FIXME( "channel type %u not implemented\n", type ); return E_NOTIMPL; } - if (binding != WS_HTTP_CHANNEL_BINDING && binding != WS_TCP_CHANNEL_BINDING) + if (binding != WS_HTTP_CHANNEL_BINDING && binding != WS_TCP_CHANNEL_BINDING && + binding != WS_UDP_CHANNEL_BINDING) { FIXME( "channel binding %u not implemented\n", binding ); return E_NOTIMPL; @@ -640,6 +654,44 @@ static HRESULT connect_channel_tcp( struct channel *channel ) return S_OK; } +static HRESULT connect_channel_udp( struct channel *channel ) +{ + struct sockaddr_storage storage; + struct sockaddr *addr = (struct sockaddr *)&storage; + int addr_len; + WS_URL_SCHEME_TYPE scheme; + WCHAR *host; + USHORT port; + HRESULT hr; + + if (channel->u.udp.socket != -1) return S_OK; + + if ((hr = parse_url( &channel->addr.url, &scheme, &host, &port )) != S_OK) return hr; + if (scheme != WS_URL_SOAPUDP_SCHEME_TYPE) + { + heap_free( host ); + return WS_E_INVALID_ENDPOINT_URL; + } + + winsock_init(); + + hr = resolve_hostname( host, port, addr, &addr_len ); + heap_free( host ); + if (hr != S_OK) return hr; + + if ((channel->u.udp.socket = socket( addr->sa_family, SOCK_DGRAM, 0 )) == -1) + return HRESULT_FROM_WIN32( WSAGetLastError() ); + + if (connect( channel->u.udp.socket, addr, addr_len ) < 0) + { + closesocket( channel->u.udp.socket ); + channel->u.udp.socket = -1; + return HRESULT_FROM_WIN32( WSAGetLastError() ); + } + + return S_OK; +} + static HRESULT connect_channel( struct channel *channel ) { switch (channel->binding) @@ -650,6 +702,9 @@ static HRESULT connect_channel( struct channel *channel ) case WS_TCP_CHANNEL_BINDING: return connect_channel_tcp( channel ); + case WS_UDP_CHANNEL_BINDING: + return connect_channel_udp( channel ); + default: ERR( "unhandled binding %u\n", channel->binding ); return E_NOTIMPL; @@ -702,6 +757,9 @@ static HRESULT send_message( struct channel *channel, WS_MESSAGE *msg ) case WS_TCP_CHANNEL_BINDING: return send_message_sock( channel->u.tcp.socket, buf.bytes, buf.length ); + case WS_UDP_CHANNEL_BINDING: + return send_message_sock( channel->u.udp.socket, buf.bytes, buf.length ); + default: ERR( "unhandled binding %u\n", channel->binding ); return E_NOTIMPL; @@ -885,6 +943,9 @@ static HRESULT receive_message( struct channel *channel ) case WS_TCP_CHANNEL_BINDING: return receive_message_sock( channel, channel->u.tcp.socket ); + case WS_UDP_CHANNEL_BINDING: + return receive_message_sock( channel, channel->u.udp.socket ); + default: ERR( "unhandled binding %u\n", channel->binding ); return E_NOTIMPL;