Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Function sf::IpAddress::getLocalAddress() on MacOS  (Read 8572 times)

0 Members and 1 Guest are viewing this topic.

Puddi

  • Newbie
  • *
  • Posts: 1
    • View Profile
Function sf::IpAddress::getLocalAddress() on MacOS
« on: June 03, 2012, 01:20:55 pm »
Hello,

My developer group and I are using the version 2.0 of the SFML and we need some network functions.

I'm the only one who use a Mac OS (version 10.7.4), the others use Ubuntu or others Linux distributions. The problem is that the function sf::IpAddress::getLocalAddress() doesn't work only on my computer. Others modules like audio, graphics, system, and window perfectly works, but I think I have a problem with the network one.

In fact, when I screen my Ip Adress in a simply program, it always return 0.0.0.0. The function :

std::cout << sf::IpAddress::getLocalAddress().toString() << std::endl;

Is it a recurrent problem or not ? And if it's not the case, where can it come from?

I'm sorry if the question have already been asked, but I don't find any solution.

Puddi Puddi

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #1 on: June 03, 2012, 04:23:57 pm »
As far as I know, it's not a known issue.

You can report it on the bug tracker.
Laurent Gomila - SFML developer

Guillermo

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #2 on: September 27, 2013, 01:41:16 am »
Has this been solve? I'm getting exactly the same.
Thanks.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #3 on: September 27, 2013, 07:35:33 am »
No. As far as I remember, there was no report on the tracker and nobody else complained about it.

Which version of SFML do you use?
Laurent Gomila - SFML developer

Guillermo

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #4 on: September 28, 2013, 03:46:05 am »
Hi, thanks for the fast respond.
I'm using the SMFL 2.1 in Mac OS X 10.8.2.
« Last Edit: September 28, 2013, 06:32:16 pm by Guillermo »

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #5 on: September 28, 2013, 10:27:27 am »
I don't have time to investigate further this weekend, but it seems that IpAddress.cpp:152 fails because of errno #49: «Can't assign requested address».
SFML / OS X developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #6 on: September 28, 2013, 05:02:42 pm »
I checked the code, and it seems that in
sockaddr_in SocketImpl::createAddress(Uint32 address, unsigned short port)
{
    sockaddr_in addr;
    std::memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
    addr.sin_addr.s_addr = htonl(address);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);

    return addr;
}
SFML only zeros out the addr.sin_zero field. According to POSIX specification, sockaddr_in should have at least sin_family, sin_port and sin_addr fields. Implementation providers are free to add more fields to the struct if they want to, and this is the case with Apple and Microsoft (and maybe Linux? I'm not sure...). Instead of only zeroing the addr.sin_zero field, SFML should zero the whole struct to make sure no uninitialized values are left in the struct. Additionally on Mac OS one should set addr.sin_len to sizeof( sockaddr_in ) as shown here.

See if making those changes helps.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Guillermo

  • Newbie
  • *
  • Posts: 3
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #7 on: September 28, 2013, 06:31:27 pm »
This is what I am doing and get 0.0.0.0:

    std::string x = sf::IpAddress::getLocalAddress().toString();
    // Create the main window
    sf::RenderWindow window(sf::VideoMode(800, 600), x);
 

 Add this in SocketImpl.cpp and nothing happened:

    std::memset(addr.sin_addr.s_addr, 0, sizeof(addr.sin_addr.s_addr));
    std::memset(addr.sin_family, 0, sizeof(addr.sin_family));
    std::memset(addr.sin_port , 0, sizeof(addr.sin_port ));
 

Even when inserting something that is not valid everything goes in the
same way, so I assume the program is not calling this file at all.

PS: Total newbie here. :)
« Last Edit: September 29, 2013, 03:50:52 am by Guillermo »

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #8 on: October 01, 2013, 07:54:31 pm »
Also tried and didn't get it working. Below my failed attempt. I will try to investigate further next weekend or next week. In the meantime, feel free to open an issue on Github so I don't forget about that.

sockaddr_in SocketImpl::createAddress(Uint32 address, unsigned short port)
{
    sockaddr_in addr;
#if defined(SFML_SYSTEM_MACOS)
    std::memset(&addr, 0, sizeof(addr));
    addr.sin_len = sizeof(addr);
#else
    std::memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
#endif
    addr.sin_addr.s_addr = htonl(address);
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(port);

    return addr;
}

SSCCE:

#include <iostream>
#include <SFML/Network.hpp>

int main(int, char const**)
{
    auto ip = sf::IpAddress::getLocalAddress();

    std::cout << ip.toString() << std::endl;
    std::cout << "error #" << errno << ": " << strerror(errno) << std::endl;

    return EXIT_SUCCESS;
}
SFML / OS X developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #9 on: October 01, 2013, 10:55:26 pm »
Strange. After searching a bit, many people seem to have solved this kind of problem with this fix.

I couldn't find anything else :-\
Laurent Gomila - SFML developer

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #10 on: October 02, 2013, 12:07:32 am »
Found it!  :D

The issue was that port 0 is not allowed for non-root apps. In fact, any port < 1024 is illegal here. Switching to 5000 fixed it on line IpAddress.cpp:151.

Setting sin_len or not changes nothing BTW.

So the questions are:

1) which port should be used?
2) what about other OSes?
3) should we memset the whole struct + set sin_len?
SFML / OS X developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #11 on: October 02, 2013, 12:55:33 am »
The issue was that port 0 is not allowed for non-root apps. In fact, any port < 1024 is illegal here. Switching to 5000 fixed it on line IpAddress.cpp:151.

1) which port should be used?
2) what about other OSes?
3) should we memset the whole struct + set sin_len?
If this was the only cause, it should be broken on any other Unix based operating system as well i.e. Linux, FreeBSD etc. They don't let non-privileged users bind on any of the "well-known ports". I think it is more a mix of many different causes that we will probably never find out. I'd just try to make everything conform to the standards as best I can and hope for the best.

If I want to know what the really official port assignments are, I always just go directly to IANA:
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
They keep the list up to date and you can be sure that most people follow it. I would stay away from port numbers marked as "Reserved" obviously. 0 is marked as such, so it wouldn't surprise me if different operating systems treated it differently.

Historically, port 0 was used to mark an endpoint as a "catch-all" kind of endpoint much like the 0.0.0.0 address is still used for nowadays. We probably can't imagine how such a port would function, especially with TCP, but it was mentioned as part of the standard: http://tools.ietf.org/html/rfc675 page 4.

If you ask me, if you want to keep this method of local address determination, you should use port 9. It is used by the Discard Protocol, and according to the description (http://tools.ietf.org/html/rfc863) it is exactly what SFML does when determining the local address ;).
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #12 on: October 02, 2013, 08:49:55 am »
If you ask me, if you want to keep this method of local address determination, you should use port 9.

Nice, it does work too for OS X. Thanks for the tip.

Can someone try on Unix/Windows? Before pushing anything theoretical I'd like to know if it works in practice (since everybody has a different interpretation of the standards).

And for 3), I'll do as you suggested and push the above impl of SocketImpl::createAddress.
SFML / OS X developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #13 on: October 02, 2013, 08:53:29 am »
Great!

Quote
And for 3), I'll do as you suggested and push the above impl of SocketImpl::createAddress.
You should change it so that you zero the structure in any case, not just on OS X.
Only the sin_len field should be conditional.

I'll test using port 9 on Windows later.
Laurent Gomila - SFML developer

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Function sf::IpAddress::getLocalAddress() on MacOS
« Reply #14 on: October 02, 2013, 08:57:11 am »
Yup, so here's the new version:

sockaddr_in SocketImpl::createAddress(Uint32 address, unsigned short port)
{
    sockaddr_in addr;
    std::memset(&addr, 0, sizeof(addr));
    addr.sin_addr.s_addr = htonl(address);
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(port);

#if defined(SFML_SYSTEM_MACOS)
    addr.sin_len = sizeof(addr);
#endif

    return addr;
}
SFML / OS X developer