<h1>Backport of <a class="issue-link js-issue-link" data-error-text="Failed to load issue title" data-id="431045139" data-permission-text="Issue title is private" data-url="https://github.com/RIOT-OS/RIOT/issues/11364" data-hovercard-type="pull_request" data-hovercard-url="/RIOT-OS/RIOT/pull/11364/hovercard" href="https://github.com/RIOT-OS/RIOT/pull/11364">#11364</a></h1>
<h3>Contribution description</h3>
<p>Calling send() on a connected UDP socket raises a kernel panic<br>
in posix_sockets.c, line 215, because sendto() is called from<br>
send() with address set to NULL.</p>
<p>This change modifies sendto() to</p>
<ul>
<li>Check if the UDP socket is connected when the address argument<br>
is NULL.</li>
<li>If connected, pass the stored remote address to socket_sendto().</li>
</ul>
<p>The reason this is not done directly in the implementation of <code>send()</code> is that <code>send()</code> is an inline function in a header file. The proposed solution here seems a bit less intrusive.</p>
<h3>Testing procedure</h3>
<p>Example code for testing (obviously, the Makefile must include <code>USEMODULE += posix_sockets</code>):</p>
<div class="highlight highlight-source-c"><pre>#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>assert.h<span class="pl-pds">></span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>errno.h<span class="pl-pds">></span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>netinet/in.h<span class="pl-pds">></span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>stdio.h<span class="pl-pds">></span></span>
#<span class="pl-k">include</span> <span class="pl-s"><span class="pl-pds"><</span>sys/socket.h<span class="pl-pds">></span></span>

<span class="pl-k">int</span> <span class="pl-en">main</span>(<span class="pl-k">void</span>)
{
    <span class="pl-k">int</span> srv = <span class="pl-c1">socket</span>(AF_INET6, SOCK_DGRAM, <span class="pl-c1">0</span>);
    <span class="pl-k">int</span> sock = <span class="pl-c1">socket</span>(AF_INET6, SOCK_DGRAM, <span class="pl-c1">0</span>);
    <span class="pl-c1">assert</span>(srv >= <span class="pl-c1">0</span> && sock >= <span class="pl-c1">0</span>);

    <span class="pl-k">struct</span> sockaddr_in6 addr;
    addr.<span class="pl-smi">sin6_family</span> = AF_INET6;
    addr.<span class="pl-smi">sin6_addr</span> = in6addr_loopback;
    addr.<span class="pl-smi">sin6_port</span> = <span class="pl-c1">htons</span>(<span class="pl-c1">7000</span>);
    <span class="pl-k">if</span> (<span class="pl-c1">bind</span>(srv, (<span class="pl-k">struct</span> sockaddr *)&addr, <span class="pl-k">sizeof</span>(<span class="pl-k">struct</span> sockaddr_in6)) != <span class="pl-c1">0</span>) {
        <span class="pl-c1">printf</span>(<span class="pl-s"><span class="pl-pds">"</span>bind failed: <span class="pl-c1">%d</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>, errno);
        <span class="pl-k">return</span> <span class="pl-c1">1</span>;
    }
    <span class="pl-k">if</span> (<span class="pl-c1">connect</span>(sock, (<span class="pl-k">struct</span> sockaddr *)&addr, <span class="pl-k">sizeof</span>(<span class="pl-k">struct</span> sockaddr_in6)) != <span class="pl-c1">0</span>) {
        <span class="pl-c1">printf</span>(<span class="pl-s"><span class="pl-pds">"</span>connect failed: <span class="pl-c1">%d</span><span class="pl-cce">\n</span><span class="pl-pds">"</span></span>, errno);
        <span class="pl-k">return</span> <span class="pl-c1">1</span>;
    }

    <span class="pl-c1">send</span>(sock, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>, <span class="pl-c1">0</span>);
    <span class="pl-k">return</span> <span class="pl-c1">0</span>;
}</pre></div>
<p><code>make term</code> without this patch results in a RIOT kernel panic:</p>
<pre><code>RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2019.04-devel-861-ga1a8d-posix_sockets_udp_connect)
sys/posix/sockets/posix_sockets.c:215 => 0x5660a44e
*** RIOT kernel panic:
FAILED ASSERTION.

*** halted.


native: exiting
</code></pre>
<p>Expected behavior with this patch applied:</p>
<pre><code>RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2019.04-devel-861-ga1a8d-posix_sockets_udp_connect)
^C
native: exiting
</code></pre>

<hr>

<h4>You can view, comment on, or merge this pull request online at:</h4>
<p>  <a href='https://github.com/RIOT-OS/RIOT/pull/11368'>https://github.com/RIOT-OS/RIOT/pull/11368</a></p>

<h4>Commit Summary</h4>
<ul>
  <li>posix_sockets.c: fix send()/write() for connected UDP sockets</li>
</ul>

<h4>File Changes</h4>
<ul>
  <li>
    <strong>M</strong>
    <a href="https://github.com/RIOT-OS/RIOT/pull/11368/files#diff-0">sys/posix/sockets/posix_sockets.c</a>
    (10)
  </li>
</ul>

<h4>Patch Links:</h4>
<ul>
  <li><a href='https://github.com/RIOT-OS/RIOT/pull/11368.patch'>https://github.com/RIOT-OS/RIOT/pull/11368.patch</a></li>
  <li><a href='https://github.com/RIOT-OS/RIOT/pull/11368.diff'>https://github.com/RIOT-OS/RIOT/pull/11368.diff</a></li>
</ul>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/RIOT-OS/RIOT/pull/11368">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AEn7YDq_pght5lXVaDmV2ztS7-M2DAR4ks5vfcpygaJpZM4cmwtK">mute the thread</a>.<img src="https://github.com/notifications/beacon/AEn7YGZ2rafbeIBNneLEBRFgwMumXJTKks5vfcpygaJpZM4cmwtK.gif" height="1" width="1" alt="" /></p>
<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/RIOT-OS/RIOT","title":"RIOT-OS/RIOT","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/RIOT-OS/RIOT"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"posix_sockets.c: fix send() for connected UDP sockets [backport 2019.04] (#11368)"}],"action":{"name":"View Pull Request","url":"https://github.com/RIOT-OS/RIOT/pull/11368"}}}</script>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/RIOT-OS/RIOT/pull/11368",
"url": "https://github.com/RIOT-OS/RIOT/pull/11368",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>