Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • I Icecast-libshout
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 20
    • Issues 20
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 1
    • Merge requests 1
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Container Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Xiph.OrgXiph.Org
  • Icecast-libshout
  • Issues
  • #2315
Closed
Open
Issue created Feb 17, 2020 by Tomasz Lemiech@szpajder

Network socket not set to nonblocking mode despite using nonblocking API

0ac7ed9e introduced a bug which causes network sockets not to be set into nonblocking mode when requested with shout_set_nonblocking(s, 1). This can be demonstrated simply by tracing an example nonblocking app.

Bad (current master HEAD):

$ strace -f -e fcntl,fcntl64,socket,connect ./nonblocking
(...)
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

Good (v2.4.3):

(...)
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 4
fcntl(4, F_SETFL, O_RDONLY|O_NONBLOCK)  = 0
connect(4, {sa_family=AF_INET, sin_port=htons(8000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now i   n progress)

In the first case fcntl is never called and the socket stays in the default (blocking) mode.

This is due to the following condition in shout_connection_connect:

    if (con->nonblocking == SHOUT_BLOCKING_DEFAULT)
        shout_connection_set_nonblocking(con, shout_get_nonblocking(shout));

But as con->nonblocking is never initialized to this value, it's effectively if(0).

Adding a simple:

    con->nonblocking = SHOUT_BLOCKING_DEFAULT;

to shout_connection_new fixes the problem. But this turns the above condition into if(1), so is it really needed? It was not there before. What's the idea behind this?

Assignee
Assign to
Time tracking