Re: Abstract sockets (linux)

2015-06-26 Thread Kagamin via Digitalmars-d-learn

On Friday, 26 June 2015 at 13:36:49 UTC, freeman wrote:

This works (socat):
connect(3, {sa_family=AF_FILE, 
path=@/var/run/ptmd.socket}, 23) = 0


This does not (from deneme, modified):
connect(3, {sa_family=AF_FILE, 
path=@/var/run/ptmd.socket}, 24) = -1 ECONNREFUSED 
(Connection refused)


Looks like contrary to other sockets, name of an abstract socket 
is treated as byte array instead of a string, hence every byte 
counts.


Re: Abstract sockets (linux)

2015-06-26 Thread freeman via Digitalmars-d-learn

On Thursday, 25 June 2015 at 15:56:06 UTC, freeman wrote:

I am having trouble using abstract sockets on Linux.

Here is sample python code that works, which works:
ptm_sockname = \0/var/run/ptmd.socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(ptm_sockname)
sock.setblocking(1)
sock.sendall('get-status detail')

Similar code in D, which does not work:
string socket_name = \0/var/run/ptmd.socket;
auto address = new UnixAddress(socket_name);
auto sock = new Socket(AddressFamily.UNIX, 
SocketType.STREAM);

scope(exit) sock.close();
sock.blocking = true;
sock.connect(address);
sock.send(get-status detail);

This is the equivalent with socat, which works:
$ echo get-status detail | socat - 
ABSTRACT-CLIENT:/var/run/ptmd.socket


My test D program exits on connect:
std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): 
Unable to connect socket: Connection refused


Any pointers?


OK, I believe I've figured it out.  The strace output I posted 
was the clue I needed to see what was going on.  The length of 
abstract sockets are seemingly improperly calculated.


In socket.d, I modified the constructor for UnixAddress as such:
this(in char[] path)
{
//len = 
cast(socklen_t)(sockaddr_un.init.sun_path.offsetof + path.length 
+ 1);
len = 
cast(socklen_t)(sockaddr_un.init.sun_path.offsetof + path.length);

writefln(inside UnixSocket, len is %s, len);
sun = cast(sockaddr_un*) (new ubyte[len]).ptr;
sun.sun_family = AF_UNIX;
sun.sun_path.ptr[0..path.length] = (cast(byte[]) 
path)[];

sun.sun_path.ptr[path.length] = 0;
}

This also explains why Ali's client/server code works with 
itself, but it doesn't work with my test case.


This seems to be a bug in socket.d.  If the first character of 
the path is a null character, do not add 1 to the length.  I 
don't have much socket programming experience, but my test code 
does work now.


My full test.d code follows, which now works as expected.  I 
compiled it with » ldc2 test.d std2/socket.d std2/socketstream.d. 
 The only modifications to socketstream.d was the module name and 
std.socket import.


import std.stdio;
import std2.socket;
import std.stream;
import std2.socketstream;

void main() {
enum string socket_name = \0/var/run/ptmd.socket;
auto address = new UnixAddress(socket_name);
writefln(path is --%s--, address.path);
writefln(length of string is --%s--, 
socket_name.length);

writefln(length of address is --%s--, address.nameLen);
auto sock = new Socket(AddressFamily.UNIX, 
SocketType.STREAM);

scope(exit) sock.close();
sock.blocking = true;
sock.connect(address);
writeln(connected!);

Stream streamer = new SocketStream(sock);
scope(exit) streamer.close();
streamer.writeLine(get-status detail);
while(true) {
auto line = streamer.readLine();
if (line.length == 0 || line == EOF) {
break;
}
writeln(line);
}
}

Is this worthy of a bug report?  Not a lot of people use abstract 
sockets, but this was certainly frustrating for my use case :)




Re: Abstract sockets (linux)

2015-06-26 Thread Ali Çehreli via Digitalmars-d-learn

On 06/26/2015 07:39 AM, freeman wrote:

 Is this worthy of a bug report?

If it's a bug, yes. :)

Ali



Re: Abstract sockets (linux)

2015-06-26 Thread freeman via Digitalmars-d-learn

On Thursday, 25 June 2015 at 19:47:37 UTC, Ali Çehreli wrote:


I've found an old example of mine, which uses abstract sockets. 
Apparently, it was a concurrency experiment as well. Just 
translated from Turkish to English:


  http://ddili.org/ornek_kod/client_server.d

One difference I see is that mine doesn't set blocking. You can 
use it like this:


1) Start it as a server:

  ./deneme --role=server

2) Start as many clients as needed:

  ./deneme --role=client

Ali

P.S. And here is the original Turkish version:

  http://ddili.org/ornek_kod/istemci_sunucu.d


Thank you for the example code!  I verified that client and 
server communicated, and that a standard file-based unix socket 
was not created.  Then I simply changed the socketName to the 
socket I was interested in, and tried the client against it.  
Still no luck unfortunately, same error as earlier.


I have noticed that successful connect calls appear to show the 
size as 23, whereas unsuccessful connect calls show 24.


This works (socat):
connect(3, {sa_family=AF_FILE, path=@/var/run/ptmd.socket}, 
23) = 0


This does not (from deneme, modified):
connect(3, {sa_family=AF_FILE, path=@/var/run/ptmd.socket}, 
24) = -1 ECONNREFUSED (Connection refused)


Re: Abstract sockets (linux)

2015-06-25 Thread freeman via Digitalmars-d-learn

On Thursday, 25 June 2015 at 18:50:29 UTC, Daniel Kozak wrote:

Any pointers?


instead of:
string socket_name = \0/var/run/ptmd.socket;
try:
string socket_name = /var/run/ptmd.socket;
works for me


It is the null character that makes it an abstract socket (see 
man unix).  There is no file /var/run/ptmd.socket, as what 
follows the null character is just a name:

$ ls -al /var/run/ptmd.socket
ls: cannot access /var/run/ptmd.socket: No such file or 
directory


Here is what happens when I remove the null:

std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): 
Unable to connect socket: No such file or directory


Re: Abstract sockets (linux)

2015-06-25 Thread Ali Çehreli via Digitalmars-d-learn

On 06/25/2015 08:56 AM, freeman wrote:

I am having trouble using abstract sockets on Linux.

Here is sample python code that works, which works:
 ptm_sockname = \0/var/run/ptmd.socket
 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 sock.connect(ptm_sockname)
 sock.setblocking(1)
 sock.sendall('get-status detail')

Similar code in D, which does not work:
 string socket_name = \0/var/run/ptmd.socket;
 auto address = new UnixAddress(socket_name);
 auto sock = new Socket(AddressFamily.UNIX, SocketType.STREAM);
 scope(exit) sock.close();
 sock.blocking = true;
 sock.connect(address);
 sock.send(get-status detail);

This is the equivalent with socat, which works:
 $ echo get-status detail | socat -
ABSTRACT-CLIENT:/var/run/ptmd.socket

My test D program exits on connect:
std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): Unable
to connect socket: Connection refused

Any pointers?


I've found an old example of mine, which uses abstract sockets. 
Apparently, it was a concurrency experiment as well. Just translated 
from Turkish to English:


  http://ddili.org/ornek_kod/client_server.d

One difference I see is that mine doesn't set blocking. You can use it 
like this:


1) Start it as a server:

  ./deneme --role=server

2) Start as many clients as needed:

  ./deneme --role=client

Ali

P.S. And here is the original Turkish version:

  http://ddili.org/ornek_kod/istemci_sunucu.d



Abstract sockets (linux)

2015-06-25 Thread freeman via Digitalmars-d-learn

I am having trouble using abstract sockets on Linux.

Here is sample python code that works, which works:
ptm_sockname = \0/var/run/ptmd.socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.connect(ptm_sockname)
sock.setblocking(1)
sock.sendall('get-status detail')

Similar code in D, which does not work:
string socket_name = \0/var/run/ptmd.socket;
auto address = new UnixAddress(socket_name);
auto sock = new Socket(AddressFamily.UNIX, SocketType.STREAM);
scope(exit) sock.close();
sock.blocking = true;
sock.connect(address);
sock.send(get-status detail);

This is the equivalent with socat, which works:
$ echo get-status detail | socat - 
ABSTRACT-CLIENT:/var/run/ptmd.socket


My test D program exits on connect:
std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): 
Unable to connect socket: Connection refused


Any pointers?


Re: Abstract sockets (linux)

2015-06-25 Thread freeman via Digitalmars-d-learn
On Thursday, 25 June 2015 at 16:07:51 UTC, Steven Schveighoffer 
wrote:
I believe there was a recently fixed bug regarding unix 
sockets. The upcoming 2.068 may help, have you tried the beta?


http://downloads.dlang.org/pre-releases/2.x/2.068.0/

-Steve


Unfortunately the problem persists (I was using ldc2 before):

$ ./test
std.socket.SocketOSException@std/socket.d(2808): Unable to 
connect socket: Connection refused


./test(_Dmain+0xce) [0x443b42]
./test(_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv+0x1f) 
[0x44ad7b]
./test(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())+0x2a) 
[0x44acd6]
./test(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll()+0x2b) [0x44ad37]
./test(void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate())+0x2a) 
[0x44acd6]

./test(_d_run_main+0x1d2) [0x44ac56]
./test(main+0x12) [0x447e96]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x7f1bff50cd5d]




Re: Abstract sockets (linux)

2015-06-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/25/15 11:56 AM, freeman wrote:

I am having trouble using abstract sockets on Linux.

Here is sample python code that works, which works:
 ptm_sockname = \0/var/run/ptmd.socket
 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 sock.connect(ptm_sockname)
 sock.setblocking(1)
 sock.sendall('get-status detail')

Similar code in D, which does not work:
 string socket_name = \0/var/run/ptmd.socket;
 auto address = new UnixAddress(socket_name);
 auto sock = new Socket(AddressFamily.UNIX, SocketType.STREAM);
 scope(exit) sock.close();
 sock.blocking = true;
 sock.connect(address);
 sock.send(get-status detail);

This is the equivalent with socat, which works:
 $ echo get-status detail | socat -
ABSTRACT-CLIENT:/var/run/ptmd.socket

My test D program exits on connect:
std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): Unable
to connect socket: Connection refused

Any pointers?


I believe there was a recently fixed bug regarding unix sockets. The 
upcoming 2.068 may help, have you tried the beta?


http://downloads.dlang.org/pre-releases/2.x/2.068.0/

-Steve


Re: Abstract sockets (linux)

2015-06-25 Thread Daniel Kozak via Digitalmars-d-learn

On Thu, 25 Jun 2015 15:56:04 +
freeman via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 I am having trouble using abstract sockets on Linux.
 
 Here is sample python code that works, which works:
  ptm_sockname = \0/var/run/ptmd.socket
  sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
  sock.connect(ptm_sockname)
  sock.setblocking(1)
  sock.sendall('get-status detail')
 
 Similar code in D, which does not work:
  string socket_name = \0/var/run/ptmd.socket;
  auto address = new UnixAddress(socket_name);
  auto sock = new Socket(AddressFamily.UNIX, SocketType.STREAM);
  scope(exit) sock.close();
  sock.blocking = true;
  sock.connect(address);
  sock.send(get-status detail);
 
 This is the equivalent with socat, which works:
  $ echo get-status detail | socat - 
 ABSTRACT-CLIENT:/var/run/ptmd.socket
 
 My test D program exits on connect:
 std.socket.SocketOSException@runtime/phobos/std/socket.d(2674): 
 Unable to connect socket: Connection refused
 
 Any pointers?

instead of:
string socket_name = \0/var/run/ptmd.socket;
try:
string socket_name = /var/run/ptmd.socket;
works for me