throw new ArgumentException ("socketAddress is not a unix socket address.");
*/
+ if (socketAddress.Size == 2) {
+ // Empty filename.
+ // Probably from RemoteEndPoint which on linux does not return the file name.
+ UnixEndPoint uep = new UnixEndPoint ("a");
+ uep.filename = "";
+ return uep;
+ }
byte [] bytes = new byte [socketAddress.Size - 2 - 1];
for (int i = 0; i < bytes.Length; i++) {
bytes [i] = socketAddress [i + 2];
#if !TARGET_JVM
// Returns the local endpoint details in addr and port
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, out int error);
+ private extern static SocketAddress LocalEndPoint_internal(IntPtr socket, int family, out int error);
#endif
// Wish: support non-IP endpoints.
SocketAddress sa;
int error;
- sa=LocalEndPoint_internal(socket, out error);
+ sa=LocalEndPoint_internal(socket, (int) address_family, out error);
if (error != 0)
throw new SocketException (error);
// Returns the remote endpoint details in addr and port
[MethodImplAttribute(MethodImplOptions.InternalCall)]
- private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, out int error);
+ private extern static SocketAddress RemoteEndPoint_internal(IntPtr socket, int family, out int error);
public EndPoint RemoteEndPoint {
get {
SocketAddress sa;
int error;
- sa=RemoteEndPoint_internal(socket, out error);
+ sa=RemoteEndPoint_internal(socket, (int) address_family, out error);
if (error != 0)
throw new SocketException (error);
ICALL(SOCK_7, "GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal)
ICALL(SOCK_8, "GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal)
ICALL(SOCK_9, "Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal)
-ICALL(SOCK_10, "LocalEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal)
+ICALL(SOCK_10, "LocalEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal)
ICALL(SOCK_11, "Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal)
ICALL(SOCK_11a, "Receive_internal(intptr,System.Net.Sockets.Socket/WSABUF[],System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_array_internal)
ICALL(SOCK_12, "Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_internal)
ICALL(SOCK_13, "RecvFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal)
-ICALL(SOCK_14, "RemoteEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal)
+ICALL(SOCK_14, "RemoteEndPoint_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal)
ICALL(SOCK_15, "Select_internal(System.Net.Sockets.Socket[]&,int,int&)", ves_icall_System_Net_Sockets_Socket_Select_internal)
ICALL(SOCK_15a, "SendFile(intptr,string,byte[],byte[],System.Net.Sockets.TransmitFileOptions)", ves_icall_System_Net_Sockets_Socket_SendFile)
ICALL(SOCK_16, "SendTo_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_SendTo_internal)
}
}
-extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 *error)
+static int
+get_sockaddr_size (int family)
+{
+ int size;
+
+ size = 0;
+ if (family == AF_INET) {
+ size = sizeof (struct sockaddr_in);
+#ifdef AF_INET6
+ } else if (family == AF_INET6) {
+ size = sizeof (struct sockaddr_in6);
+#endif
+#ifdef HAVE_SYS_UN_H
+ } else if (family == AF_UNIX) {
+ size = sizeof (struct sockaddr_un);
+#endif
+ }
+ return size;
+}
+
+extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 af, gint32 *error)
{
- gchar sa[32]; /* sockaddr in not big enough for sockaddr_in6 */
+ gchar *sa;
socklen_t salen;
int ret;
+ MonoObject *result;
MONO_ARCH_SAVE_REGS;
*error = 0;
- salen=sizeof(sa);
+ salen = get_sockaddr_size (convert_family (af));
+ if (salen == 0) {
+ *error = WSAEAFNOSUPPORT;
+ return NULL;
+ }
+ sa = g_malloc0 (salen);
ret = _wapi_getsockname (sock, (struct sockaddr *)sa, &salen);
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
+ g_free (sa);
return(NULL);
}
LOGDEBUG (g_message("%s: bound to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)&sa)->sin_addr), ntohs(((struct sockaddr_in *)&sa)->sin_port)));
- return(create_object_from_sockaddr((struct sockaddr *)sa, salen,
- error));
+ result = create_object_from_sockaddr((struct sockaddr *)sa, salen, error);
+ g_free (sa);
+ return result;
}
-extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 *error)
+extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 af, gint32 *error)
{
- gchar sa[32]; /* sockaddr in not big enough for sockaddr_in6 */
+ gchar *sa;
socklen_t salen;
int ret;
+ MonoObject *result;
MONO_ARCH_SAVE_REGS;
*error = 0;
- salen=sizeof(sa);
+ salen = get_sockaddr_size (convert_family (af));
+ if (salen == 0) {
+ *error = WSAEAFNOSUPPORT;
+ return NULL;
+ }
+ sa = g_malloc0 (salen);
+ /* Note: linux returns just 2 for AF_UNIX. Always. */
ret = _wapi_getpeername (sock, (struct sockaddr *)sa, &salen);
-
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
+ g_free (sa);
return(NULL);
}
LOGDEBUG (g_message("%s: connected to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)&sa)->sin_addr), ntohs(((struct sockaddr_in *)&sa)->sin_port)));
- return(create_object_from_sockaddr((struct sockaddr *)sa, salen,
- error));
+ result = create_object_from_sockaddr((struct sockaddr *)sa, salen, error);
+ g_free (sa);
+ return result;
}
static struct sockaddr *create_sockaddr_from_object(MonoObject *saddr_obj,
extern void ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock, gboolean block, gint32 *error) MONO_INTERNAL;
extern gpointer ves_icall_System_Net_Sockets_Socket_Accept_internal(SOCKET sock, gint32 *error, gboolean blocking) MONO_INTERNAL;
extern void ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock, guint32 backlog, gint32 *error) MONO_INTERNAL;
-extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;
-extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 *error) MONO_INTERNAL;
+extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 af, gint32 *error) MONO_INTERNAL;
+extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 af, gint32 *error) MONO_INTERNAL;
extern void ves_icall_System_Net_Sockets_Socket_Bind_internal(SOCKET sock, MonoObject *sockaddr, gint32 *error) MONO_INTERNAL;
extern void ves_icall_System_Net_Sockets_Socket_Connect_internal(SOCKET sock, MonoObject *sockaddr, gint32 *error) MONO_INTERNAL;
extern gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error) MONO_INTERNAL;