API login problem on RB133

Hello

I am testing API recently to find out how to use in production networks.
I’ve found one case wchich seams to be a bug.
I use PHP API class from WIKI (slighlty modified for my needs).

This is what i am getting from RB133:

Connecting to MT 192.168.1.100
Connection attempt #1 to 192.168.1.100:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !done
Connection attempt #2 to 192.168.1.100:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !done
Connection attempt #3 to 192.168.1.100:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !done
Connection attempt #4 to 192.168.1.100:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !done
Connection attempt #5 to 192.168.1.100:8728...
<<< [6] /login
>>> [5/5 bytes read.
>>> [5, 0] !done
Error...

Where is RET message gone ??

to make sure i used a packet sniffer to see if its a my class problem, but no… Routerboard is not sending back RET messages !!!

EDIT
ALix, PC RB433 and 411 works ok
all platform tested with version 3.20

try to insert pauses between connections attempts.

thanks a lot.

Acctually sleep between connection attempts was not an issue. problem is solved when i addes sleep into connect function beetween those two lines in function connect:

                        if ($this->socket = @fsockopen($ip, $this->port, $this->error_no, $this->error_str, $this->timeout) ) {

                                socket_set_timeout($this->socket, $this->timeout);

                                $this->write('/login');
                                sleep(2);
                                $RESPONSE = $this->read(false);

                                if ($RESPONSE[0] == '!done') {

This solved a problem with establishing a connection.

Analize:

generating HASH key of RET message take some time, and due to low performance of RB133 i could not make a succesful connection.

this can be solved if PHP API class would use a “nonblocking” way of reading from socket.

Am I right ?

to know for sure if there is or is not a problem, go to wiki and in API article there is python example. try if that is working - if it is, there is no problem, if it is not, you have some misconfiguration on your router.

first place to check is /ip services, is your api enabled?

what misconfiguration ?

Janis with all respect, but try to read more carefully :wink:

with al due respect, have you tried what i suggested?

as topic clearly states - API does not work on RB133, it is not say that using API PHP implementation that you have modified, and we do not know what changes you made, does not work.

so where you would suggest to look for problem first, your modified client or API, if we see topic and that little info in your post?

so, eliminate API first - simple, python, run python api implementation and see, if you can connect.

Janis is trying to suggest, that you try another programming language without modifications, so that you know where is the bug - in the API, or in your PHP code modifications

I understand, both of you. It is problem with Client implementation.

I have this problem but sleep don’t help!
Connection attempt #1 to x.x.x.x:a8728… Connection attempt #2 to x.x.x.x:8728… Connection attempt #3 to x.x.x.x:8728… Connection attempt #4 to x.x.x.x:8728… Connection attempt #5 to x.x.x.x:8728… Error…


On local my program work well but on any online web server doesn’t work!!!

check if API service is enabled under /ip services.

Sorry for digging out subject, but i spent few hours on this issue!!

I can confirm that problem. I used wireshark and packet sniffer to find the problem.

            if ($this->socket = @fsockopen($ip, $this->port, $this->error_no, $this->error_str, $this->timeout)) {
                socket_set_timeout($this->socket, $this->timeout);
                $this->write('/login');
                $RESPONSE = $this->read(false);  //when !done and =ret=.... comes in one packet everything is OK
but when =ret= arrives in different packet than !done we have $STATUS['unread_bytes'] eq ZERO after reading done, and connecting loop breaks. For me it is enough to wait few ms after write, befor read to solve the problem             
   if ($RESPONSE[0] == '!done') {
                    if (preg_match_all('/[^=]+/i', $RESPONSE[1], $MATCHES)) {
[...]

what happens whel list has a lot of =ret=? (list is large enough to not to fit into one packet?\

and what RouterOS version you are running? Also, you can see this only on mentioned router?

if possible, please try latest RouterOS release.

5.19 RB433AH and RB600A
I think that dividing data into 2 packets is not caused by the size of data, but by the time of generatioin =ret=

in jpg there is failed attempt to login packets 1-14, and successfull login all packets below.

when i wait 10 ms after write, before read i tried to login 100 times, every was sussesfull.

…lot of ret…? i noticed this problem only on login
a.jpg

What PHP version are you having? PHP versions before PHP 5.3.4 are known to be somewhat quirky with fragmenting small and/or untimely socket data.

Note that even modern versions fragment large and/or excessively untimely data, and the PHP API class was not designed with that in mind. Try my implementation instead, which takes care of assembling all pieces (regardless of how PHP decides to fragment them). It requires PHP 5.3.0 at minimum though.

PHP Version 5.3.3-7+squeeze13

Assuming squeeze13 is your OS and version (a code name of a Debian release according to Wikipedia)… what do you mean with “5.3.3-7”? That you’ve tried with 5.3.3 and 5.3.7, with all releases between 5.3.3 and 5.3.7, or is this some kind of 5.3.3 snapshot (that happens to be 7th in some series)?

Regardless, my implementation should work with this setup. Try it. Please.

i’ve copied it from phpinfo() function
ver.jpg

I’m having the same problem with intermittent login failures. I get a failure about one time in 10.

RB433L, ROS 5.19. Using the C client from the wiki. The compiled binary is running on a single board computer, running linux, directly connected via a short CAT5 jumper to ether1 of the RB433L.

To be fair, I did make a change to the calling routine in the wiki to compile in a static command list. If I were Mikrotik, I’d also ask me to use the un-altered C client. I will do that tomorrow.

I’ll also try the 2-second delay between write and read. Maybe I’ll break out the wireshark and see if I see the packet boundary issues.

Any other suggestions will be welcome.

For C, there was a binary safety issue that is still not resolved in the current wiki code. See this topic for details, and a possible (not exactly elegant, but still working) fix.

It should also be noted that the C code also doesn’t account for fragmented/untimely data. In fact, a quick inspection at all clients shows that other than my client, the Python (both 2 and 3; shows why janisk suggested it before), C-Winsock, C++, NodeJS, Perl and the .NET clients take care of that (.NET clients do it very inefficiently - byte by byte, instead of chunks, but still…). Other implementations (other than the C client, I inspected Ruby, Java, ActionScript and Delphi clients) assume that saying N bytes to a socket function means you get N bytes, which is not true.

as far as i have seen it, java somehow takes care of that or i have not encountered situation that java code failed due to reply fragmentation.

However in C/C++ i had to make reading in a loop until i read whole length of the reply and use non-blocking sockets.