<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rapapaing</title>
	<atom:link href="http://www.rapapaing.com/blog/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.rapapaing.com/blog</link>
	<description>Games, programming and everything in between</description>
	<lastBuildDate>Mon, 13 Feb 2012 07:47:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>How to do UDP hole punching</title>
		<link>http://www.rapapaing.com/blog/?p=24</link>
		<comments>http://www.rapapaing.com/blog/?p=24#comments</comments>
		<pubDate>Tue, 26 Jul 2011 14:41:35 +0000</pubDate>
		<dc:creator>Oscar Rodríguez</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[hole punching]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sockets]]></category>
		<category><![CDATA[udp]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.rapapaing.com/blog/?p=24</guid>
		<description><![CDATA[I will now show you how to do UDP hole punching, with code in C. Hole punching is an advanced networking concept, so you&#8217;re expected to at least know how to compile/run this code. I have written lots of comments inside the code to explain what is happening. To use this, run the server code [...]]]></description>
			<content:encoded><![CDATA[<p>I will now show you how to do <a href="http://alumnus.caltech.edu/~dank/peer-nat.html" target="_blank">UDP hole punching</a>, with code in C. Hole punching is an advanced networking concept, so you&#8217;re expected to at least know how to compile/run this code.</p>
<p>I have written lots of comments inside the code to explain what is happening.</p>
<p>To use this, run the server code in a computer with a public IP address, and then run the client code in two or more different computers, each behind a different NAT.</p>
<p>I compiled and tested this on Ubuntu Server 11.04 and CentOS 5, it should work easily in probably all other linuces and BSDs. It could run in Windows using the WSA code. This code is also not endianness-safe, so it would be best to run it on x86-64 or similar in all machines.</p>
<p>I release this code to the public domain, but you&#8217;re a complete lunatic if you plan to use this code in any real program.</p>
<p>server code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// UDP hole punching example, server code</span>
<span style="color: #666666; font-style: italic;">// Base UDP code stolen from http://www.abc.se/~m6695/udp.html</span>
<span style="color: #666666; font-style: italic;">// By Oscar Rodriguez</span>
<span style="color: #666666; font-style: italic;">// This code is public domain, but you're a complete lunatic</span>
<span style="color: #666666; font-style: italic;">// if you plan to use this code in any real program.</span>
&nbsp;
<span style="color: #339933;">#include &lt;arpa/inet.h&gt;</span>
<span style="color: #339933;">#include &lt;netinet/in.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/types.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/socket.h&gt;</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
<span style="color: #339933;">#include &lt;string.h&gt;</span>
&nbsp;
<span style="color: #339933;">#define BUFLEN 512</span>
<span style="color: #339933;">#define NPACK 10</span>
<span style="color: #339933;">#define PORT 9930</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// A small struct to hold a UDP endpoint. We'll use this to hold each client's endpoint.</span>
<span style="color: #993333;">struct</span> client
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> host<span style="color: #339933;">;</span>
    <span style="color: #993333;">short</span> port<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Just a function to kill the program when something goes wrong.</span>
<span style="color: #993333;">void</span> diep<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>s<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    perror<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">struct</span> sockaddr_in si_me<span style="color: #339933;">,</span> si_other<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> s<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> j<span style="color: #339933;">,</span> slen<span style="color: #339933;">=</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">char</span> buf<span style="color: #009900;">&#91;</span>BUFLEN<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> client clients<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 10 clients. Notice that we're not doing any bound checking.</span>
    <span style="color: #993333;">int</span> n <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Create a UDP socket</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">=</span>socket<span style="color: #009900;">&#40;</span>AF_INET<span style="color: #339933;">,</span> SOCK_DGRAM<span style="color: #339933;">,</span> IPPROTO_UDP<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;socket&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// si_me stores our local endpoint. Remember that this program</span>
    <span style="color: #666666; font-style: italic;">// has to be run in a network with UDP endpoint previously known</span>
    <span style="color: #666666; font-style: italic;">// and directly accessible by all clients. In simpler terms, the</span>
    <span style="color: #666666; font-style: italic;">// server cannot be behind a NAT.</span>
    memset<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>si_me<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_me<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    si_me.<span style="color: #202020;">sin_family</span> <span style="color: #339933;">=</span> AF_INET<span style="color: #339933;">;</span>
    si_me.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> htons<span style="color: #009900;">&#40;</span>PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    si_me.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">=</span> htonl<span style="color: #009900;">&#40;</span>INADDR_ANY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>bind<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_me<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_me<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;bind&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// When a new client sends a datagram...</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>recvfrom<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> buf<span style="color: #339933;">,</span> BUFLEN<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>slen<span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
            diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;recvfrom&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// The client's public UDP endpoint data is now in si_other.</span>
        <span style="color: #666666; font-style: italic;">// Notice that we're completely ignoring the datagram payload.</span>
        <span style="color: #666666; font-style: italic;">// If we want to support multiple clients inside the same NAT,</span>
        <span style="color: #666666; font-style: italic;">// we'd have clients send their own private UDP endpoints</span>
        <span style="color: #666666; font-style: italic;">// encoded in some way inside the payload, and store those as</span>
        <span style="color: #666666; font-style: italic;">// well.</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Received packet from %s:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> inet_ntoa<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_addr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ntohs<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// Now we add the client's UDP endpoint in our list.</span>
        clients<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span> <span style="color: #339933;">=</span> si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span><span style="color: #339933;">;</span>
        clients<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span> <span style="color: #339933;">=</span> si_other.<span style="color: #202020;">sin_port</span><span style="color: #339933;">;</span>
        n<span style="color: #339933;">++;</span>
        <span style="color: #666666; font-style: italic;">// And then tell everybody about everybody's public UDP endpoints</span>
        <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> n<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">=</span> clients<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span><span style="color: #339933;">;</span>
            si_other.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> clients<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">// We send a datagram for each client in our list. Of course,</span>
            <span style="color: #666666; font-style: italic;">// we could also assemble a single datagram and send that.</span>
            <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>j <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> j <span style="color: #339933;">&lt;</span> n<span style="color: #339933;">;</span> j<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// The payload is the client's public UDP endpoint, clients[j]</span>
                <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Sending to %s:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> inet_ntoa<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_addr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ntohs<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #666666; font-style: italic;">// We're sending binary data here, using the server's byte order.</span>
                <span style="color: #666666; font-style: italic;">// In your code, you should make sure every client agrees on the endianness.</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>sendto<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>clients<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">6</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> slen<span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
                    diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sendto&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Now we have %d clients<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// And we go back to listening. Notice that since UDP has no notion</span>
        <span style="color: #666666; font-style: italic;">// of connections, we can use the same socket to listen for data</span>
        <span style="color: #666666; font-style: italic;">// from different clients.</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Actually, we never reach this point...</span>
    close<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>client code:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
</pre></td><td class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// UDP hole punching example, client code</span>
<span style="color: #666666; font-style: italic;">// Base UDP code stolen from http://www.abc.se/~m6695/udp.html</span>
<span style="color: #666666; font-style: italic;">// By Oscar Rodriguez</span>
<span style="color: #666666; font-style: italic;">// This code is public domain, but you're a complete lunatic</span>
<span style="color: #666666; font-style: italic;">// if you plan to use this code in any real program.</span>
&nbsp;
<span style="color: #339933;">#include &lt;arpa/inet.h&gt;</span>
<span style="color: #339933;">#include &lt;netinet/in.h&gt;</span>
<span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/types.h&gt;</span>
<span style="color: #339933;">#include &lt;sys/socket.h&gt;</span>
<span style="color: #339933;">#include &lt;unistd.h&gt;</span>
<span style="color: #339933;">#include &lt;stdlib.h&gt;</span>
<span style="color: #339933;">#include &lt;string.h&gt;</span>
&nbsp;
<span style="color: #339933;">#define BUFLEN 512</span>
<span style="color: #339933;">#define NPACK 10</span>
<span style="color: #339933;">#define PORT 9930</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// This is our server's IP address. In case you're wondering, this one is an RFC 5737 address.</span>
<span style="color: #339933;">#define SRV_IP &quot;203.0.113.61&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// A small struct to hold a UDP endpoint. We'll use this to hold each peer's endpoint.</span>
<span style="color: #993333;">struct</span> client
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> host<span style="color: #339933;">;</span>
    <span style="color: #993333;">short</span> port<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Just a function to kill the program when something goes wrong.</span>
<span style="color: #993333;">void</span> diep<span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span>s<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    perror<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    exit<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">int</span> main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span><span style="color: #339933;">*</span> argv<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">struct</span> sockaddr_in si_me<span style="color: #339933;">,</span> si_other<span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> s<span style="color: #339933;">,</span> i<span style="color: #339933;">,</span> f<span style="color: #339933;">,</span> j<span style="color: #339933;">,</span> k<span style="color: #339933;">,</span> slen<span style="color: #339933;">=</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> client buf<span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> client server<span style="color: #339933;">;</span>
    <span style="color: #993333;">struct</span> client peers<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 10 peers. Notice that we're not doing any bound checking.</span>
    <span style="color: #993333;">int</span> n <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">=</span>socket<span style="color: #009900;">&#40;</span>AF_INET<span style="color: #339933;">,</span> SOCK_DGRAM<span style="color: #339933;">,</span> IPPROTO_UDP<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;socket&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Our own endpoint data</span>
    memset<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>si_me<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_me<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    si_me.<span style="color: #202020;">sin_family</span> <span style="color: #339933;">=</span> AF_INET<span style="color: #339933;">;</span>
    si_me.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> htons<span style="color: #009900;">&#40;</span>PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// This is not really necessary, we can also use 0 (any port)</span>
    si_me.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">=</span> htonl<span style="color: #009900;">&#40;</span>INADDR_ANY<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// The server's endpoint data</span>
    memset<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>si_other<span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    si_other.<span style="color: #202020;">sin_family</span> <span style="color: #339933;">=</span> AF_INET<span style="color: #339933;">;</span>
    si_other.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> htons<span style="color: #009900;">&#40;</span>PORT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>inet_aton<span style="color: #009900;">&#40;</span>SRV_IP<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>si_other.<span style="color: #202020;">sin_addr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">==</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;aton&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Store the server's endpoint data so we can easily discriminate between server and peer datagrams.</span>
    server.<span style="color: #202020;">host</span> <span style="color: #339933;">=</span> si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span><span style="color: #339933;">;</span>
    server.<span style="color: #202020;">port</span> <span style="color: #339933;">=</span> si_other.<span style="color: #202020;">sin_port</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Send a simple datagram to the server to let it know of our public UDP endpoint.</span>
    <span style="color: #666666; font-style: italic;">// Not only the server, but other clients will send their data through this endpoint.</span>
    <span style="color: #666666; font-style: italic;">// The datagram payload is irrelevant, but if we wanted to support multiple</span>
    <span style="color: #666666; font-style: italic;">// clients behind the same NAT, we'd send our won private UDP endpoint information</span>
    <span style="color: #666666; font-style: italic;">// as well.</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>sendto<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;hi&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> slen<span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sendto&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Right here, our NAT should have a session entry between our host and the server.</span>
    <span style="color: #666666; font-style: italic;">// We can only hope our NAT maps the same public endpoint (both host and port) when we</span>
    <span style="color: #666666; font-style: italic;">// send datagrams to other clients using our same private endpoint.</span>
    <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">// Receive data from the socket. Notice that we use the same socket for server and</span>
        <span style="color: #666666; font-style: italic;">// peer communications. We discriminate by using the remote host endpoint data, but</span>
        <span style="color: #666666; font-style: italic;">// remember that IP addresses are easily spoofed (actually, that's what the NAT is</span>
        <span style="color: #666666; font-style: italic;">// doing), so remember to do some kind of validation in here.</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>recvfrom<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>buf<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>buf<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">&amp;</span>slen<span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
            diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;recvfrom&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Received packet from %s:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> inet_ntoa<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_addr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ntohs<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>server.<span style="color: #202020;">host</span> <span style="color: #339933;">==</span> si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">&amp;&amp;</span> server.<span style="color: #202020;">port</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">short</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// The datagram came from the server. The server code is set to send us a</span>
            <span style="color: #666666; font-style: italic;">// datagram for each peer, in which the payload contains the peer's UDP</span>
            <span style="color: #666666; font-style: italic;">// endpoint data. We're receiving binary data here, sent using the server's</span>
            <span style="color: #666666; font-style: italic;">// byte ordering. We should make sure we agree on the endianness in any</span>
            <span style="color: #666666; font-style: italic;">// serious code.</span>
            f <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">// Now we just have to add the reported peer into our peer list</span>
            <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> n <span style="color: #339933;">&amp;&amp;</span> f <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span> <span style="color: #339933;">==</span> buf.<span style="color: #202020;">host</span> <span style="color: #339933;">&amp;&amp;</span> peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span> <span style="color: #339933;">==</span> buf.<span style="color: #202020;">port</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    f <span style="color: #339933;">=</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #666666; font-style: italic;">// Only add it if we didn't have it before.</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>f <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                peers<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span> <span style="color: #339933;">=</span> buf.<span style="color: #202020;">host</span><span style="color: #339933;">;</span>
                peers<span style="color: #009900;">&#91;</span>n<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span> <span style="color: #339933;">=</span> buf.<span style="color: #202020;">port</span><span style="color: #339933;">;</span>
                n<span style="color: #339933;">++;</span>
            <span style="color: #009900;">&#125;</span>
            si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">=</span> buf.<span style="color: #202020;">host</span><span style="color: #339933;">;</span>
            si_other.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> buf.<span style="color: #202020;">port</span><span style="color: #339933;">;</span>
            <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Added peer %s:%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> inet_ntoa<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_addr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ntohs<span style="color: #009900;">&#40;</span>si_other.<span style="color: #202020;">sin_port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Now we have %d peers<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">// And here is where the actual hole punching happens. We are going to send</span>
            <span style="color: #666666; font-style: italic;">// a bunch of datagrams to each peer. Since we're using the same socket we</span>
            <span style="color: #666666; font-style: italic;">// previously used to send data to the server, our local endpoint is the same</span>
            <span style="color: #666666; font-style: italic;">// as before.</span>
            <span style="color: #666666; font-style: italic;">// If the NAT maps our local endpoint to the same public endpoint</span>
            <span style="color: #666666; font-style: italic;">// regardless of the remote endpoint, after the first datagram we send, we</span>
            <span style="color: #666666; font-style: italic;">// have an open session (the hole punch) between our local endpoint and the</span>
            <span style="color: #666666; font-style: italic;">// peer's public endpoint. The first datagram will probably not go through</span>
            <span style="color: #666666; font-style: italic;">// the peer's NAT, but since UDP is stateless, there is no way for our NAT</span>
            <span style="color: #666666; font-style: italic;">// to know that the datagram we sent got dropped by the peer's NAT (well,</span>
            <span style="color: #666666; font-style: italic;">// our NAT may get an ICMP Destination Unreachable, but most NATs are</span>
            <span style="color: #666666; font-style: italic;">// configured to simply discard them) but when the peer sends us a datagram,</span>
            <span style="color: #666666; font-style: italic;">// it will pass through the hole punch into our local endpoint.</span>
            <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>k <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> k <span style="color: #339933;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span> k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Send 10 datagrams.</span>
                <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> n<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    si_other.<span style="color: #202020;">sin_addr</span>.<span style="color: #202020;">s_addr</span> <span style="color: #339933;">=</span> peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span><span style="color: #339933;">;</span>
                    si_other.<span style="color: #202020;">sin_port</span> <span style="color: #339933;">=</span> peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span><span style="color: #339933;">;</span>
                    <span style="color: #666666; font-style: italic;">// Once again, the payload is irrelevant. Feel free to send your VoIP</span>
                    <span style="color: #666666; font-style: italic;">// data in here.</span>
                    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>sendto<span style="color: #009900;">&#40;</span>s<span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;hi&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">struct</span> sockaddr<span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>si_other<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> slen<span style="color: #009900;">&#41;</span><span style="color: #339933;">==-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span>
                        diep<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;sendto()&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
        <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">// The datagram came from a peer</span>
            <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> n<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>
                <span style="color: #666666; font-style: italic;">// Identify which peer it came from</span>
                <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">host</span> <span style="color: #339933;">==</span> buf.<span style="color: #202020;">host</span> <span style="color: #339933;">&amp;&amp;</span> peers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">port</span> <span style="color: #339933;">==</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">short</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>buf.<span style="color: #202020;">port</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                <span style="color: #009900;">&#123;</span>
                    <span style="color: #666666; font-style: italic;">// And do something useful with the received payload</span>
                    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Received from peer %d!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
&nbsp;
            <span style="color: #666666; font-style: italic;">// It is possible to get data from an unregistered peer. These are some reasons</span>
            <span style="color: #666666; font-style: italic;">// I quickly came up with, in which this can happen:</span>
            <span style="color: #666666; font-style: italic;">// 1. The server's datagram notifying us with the peer's address got lost,</span>
            <span style="color: #666666; font-style: italic;">//    or it hasn't arrived yet (likely)</span>
            <span style="color: #666666; font-style: italic;">// 2. A malicious (or clueless) user is sending you data on this endpoint (maybe</span>
            <span style="color: #666666; font-style: italic;">//    unlikely)</span>
            <span style="color: #666666; font-style: italic;">// 3. The peer's public endpoint changed either because the session timed out,</span>
            <span style="color: #666666; font-style: italic;">//    or because its NAT did not assign the same public endpoint when sending</span>
            <span style="color: #666666; font-style: italic;">//    datagrams to different remote endpoints. If this happens, and we're able</span>
            <span style="color: #666666; font-style: italic;">//    to detect this situation, we could change our peer's endpoint data to</span>
            <span style="color: #666666; font-style: italic;">//    the correct one. If we manage to pull this off correctly, even if at most</span>
            <span style="color: #666666; font-style: italic;">//    one client has a NAT that doesn't support hole punching, we can communicate</span>
            <span style="color: #666666; font-style: italic;">//    directly between both peers.</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Actually, we never reach this point...</span>
    close<span style="color: #009900;">&#40;</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.rapapaing.com/blog/?feed=rss2&#038;p=24</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Relaunch of Rapapaing</title>
		<link>http://www.rapapaing.com/blog/?p=20</link>
		<comments>http://www.rapapaing.com/blog/?p=20#comments</comments>
		<pubDate>Fri, 11 Feb 2011 11:02:48 +0000</pubDate>
		<dc:creator>Oscar Rodríguez</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rapapaing.com/blog/?p=20</guid>
		<description><![CDATA[It&#8217;s now been almost 9 years since I first launched rapapaing.com. It seems like it was yesterday! The Internet is changing, and writing content by directly writing HTML is so pre-2010. So I&#8217;ve decided I should give the page a makeup and relaunch it, this time as a blog. Fear not, as there was no [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s now been almost 9 years since I first launched rapapaing.com. It seems like it was yesterday!</p>
<p>The Internet is changing, and writing content by directly writing HTML is so pre-2010. So I&#8217;ve decided I should give the page a makeup and relaunch it, this time as a blog. Fear not, as there was no downtime, no 404 pages during the migration,  I have kept most of the previous content, and every old link is still valid, though they now point to places inside this blog thanks to our friends ModRewrite and HTTP code 301. However, it is possible that I messed up somewhere, so please let me know if an old link is broken.</p>
<p>Additionally, I&#8217;ve kept the minimalist retro look and feel, but instead of a gray page, previously found on the main page, I am now using the red I used on my personal page. Thanks a lot to the guys at <a href="http://www.plaintxt.org" target="_blank">plaintxt</a> for this awesome theme.</p>
<p>But also times have changed. I am now a professional game programmer, and I wish to write a little bit more about my thoughts on game programming, design, content creation, and the game industry itself.</p>
<p>So, if you were a regular visitor, welcome back. If you&#8217;re a new visitor, welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rapapaing.com/blog/?feed=rss2&#038;p=20</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to draw Pixel Art clouds quickly</title>
		<link>http://www.rapapaing.com/blog/?p=12</link>
		<comments>http://www.rapapaing.com/blog/?p=12#comments</comments>
		<pubDate>Fri, 11 Feb 2011 10:37:05 +0000</pubDate>
		<dc:creator>Oscar Rodríguez</dc:creator>
				<category><![CDATA[Art]]></category>
		<category><![CDATA[Clouds]]></category>
		<category><![CDATA[Drawing]]></category>
		<category><![CDATA[Pixel art]]></category>

		<guid isPermaLink="false">http://www.rapapaing.com/blog/?p=12</guid>
		<description><![CDATA[Well, if you&#8217;re into pixel art like me, you will eventually want to draw some kind of landscape. Regardless of whether it&#8217;s for a game or a simple illustration, you will end up having to draw a sky, and if you&#8217;re like me, you&#8217;ll start by drawing some blue, and then&#8230; And then nothing happens. [...]]]></description>
			<content:encoded><![CDATA[<p>Well, if you&#8217;re into pixel art like me, you will eventually want to  draw some kind of landscape. Regardless of whether it&#8217;s for a game or a  simple illustration, you will end up having to draw a sky, and if you&#8217;re  like me, you&#8217;ll start by drawing some blue, and then&#8230;</p>
<p>And then nothing happens. Skies are blue, yes, but your precious and  detailed piece of pixel art seems like it is now in front of a blue  screen of death, and your blue looks horrid. That&#8217;s where you think you  need some clouds to break the monotony, but you have no idea how to draw  clouds in pixel art.</p>
<p>So you boot your browser and look for how to draw pixel art clouds,  but at least, at the time I wrote this, there are no single  comprehensive articles on how to draw pixel art clouds. I suppose this  is some kind of secret each pixel artist keeps to himself, because many  pieces of art have some nice clouds, yet nobody even mentions how to  draw them. This is where you wish you would have done an indoors scene.</p>
<p>Well, fear not. I have come to tell you of one way you can use to  draw credible pixel art clouds very quickly. This speed thing is quite  important, because you simply can&#8217;t waste hours and hours of time just  to draw a single cloud, and then when you try it on your game, it&#8217;s too  big, or too fat, or simply too useless. With this method you can draw  clouds in 1-3 minutes each. This is enough to make lots of clouds, some  of which you will keep and some of which you will erase without a single  bit of remorse.</p>
<p>This method is meant to draw <a href="http://en.wikipedia.org/wiki/Altocumulus">altocumulus</a> and <a href="http://en.wikipedia.org/wiki/Stratocumulus">stratocumulus</a> clouds, which are, in my opinion, the most cloud-like type of clouds.  This is quite important in art, remembering the old adage:</p>
<blockquote><p><em>&#8220;It doesn&#8217;t matter how real it is. What matters is how real it looks&#8221;</em></p></blockquote>
<p>Also, this method is meant to draw clouds illuminated from above (that would be between 10 AM and 2 PM).</p>
<p>You don&#8217;t <em>have</em> to draw your clouds like this, but you can  use this as a starting point for drawing your own custom clouds with all  kinds of effects for all kinds of needs. So let&#8217;s get started!</p>
<h4>Step 1</h4>
<p>The first thing you want to do is choose your color palette. Most  likely you already have your blue for your background, and that is going  to be your first and darker color. From there, start making lighter and  less saturated colors (some hue shifting wouldn&#8217;t hurt as well), until  you have 6 shades of blue. The darkest shade is your sky color, and the  lightest one should be white, or really close to it.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-0.png"><img class="alignnone size-full wp-image-13" title="Step 1" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-0.png" alt="" width="384" height="288" /></a></p>
<p>Make some rectangles with each of these colors as I have done on the  top-left corner of my picture, So you can easily access them whenever  you need them.</p>
<h4>Step 2</h4>
<p>Once you choose your colors, start by picking the lightest color and  draw some pixels resembling downward arcs, or the letter M if you like.  These are going to be the topmost pixels in your cloud. Don&#8217;t put too  much thought into these pixels, but try and make sure they&#8217;re somewhat  evenly spaced, and not too thick (especially at the borders).</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-1.png"><img class="alignnone size-full wp-image-14" title="Step 2" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-1.png" alt="" width="384" height="288" /></a></p>
<p>As you can see, I&#8217;ve drawn some two groups of pixels, one on the left  and one on the right, each one roughly going up and then down again. I  know, you need a lot of imagination to visualize this &gt;_&lt;;;; These  are the highlights of your clouds.</p>
<h4>Step 3</h4>
<p>Now with the next shade of blue draw some pixels below and to the  sides of the pixels you&#8217;ve already drawn. Think of this as building a  base for the pixels you&#8217;ve already drawn. Once again, don&#8217;t put too much  thought into what you&#8217;re drawing.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-2.png"><img class="alignnone size-full wp-image-15" title="Step 3" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-2.png" alt="" width="384" height="288" /></a></p>
<h4>Step 4</h4>
<p>Now with the darkest shade of blue that is not the background shade,  draw the bottom of the cloud. This should be drawn a little bit more  straight, but as with the first pixels, they should somewhat resemble an  upside pointing arc. Once again, don&#8217;t stress the precision of the  pixels you&#8217;re drawing, as clouds are all about randomness.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-3.png"><img class="alignnone size-full wp-image-16" title="Step 4" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-3.png" alt="" width="384" height="288" /></a></p>
<p>This is the bottom base of your cloud, and the rest of the cloud will go in between these two slices.</p>
<h4>Step 5</h4>
<p>Now, with the next lighter shade of blue, do the same as you did on  step 3, only that above the pixels you&#8217;ve just drawn. On the next step  we&#8217;re going to do a floodfill so also try and adjust the pixels in your  image so the interior of the cloud will get properly filled without  bleeding to the rest of the sky.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-4.png"><img class="alignnone size-full wp-image-17" title="Step 5" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-4.png" alt="" width="384" height="288" /></a></p>
<h4>Step 6</h4>
<p>Now with the only remaining shade of blue, floodfill the interior of  the cloud. This is quite straightforward, but now you can see most of  how the cloud will be like.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-5.png"><img class="alignnone size-full wp-image-18" title="Step 6" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-5.png" alt="" width="384" height="288" /></a></p>
<h4>Step 7</h4>
<p>Now it&#8217;s time for details. Fix any pixels that don&#8217;t look very good,  and add some other pixels where they need to be added. You should polish  your work, but once more, don&#8217;t dedicate too much time to this. Before  you finish, don&#8217;t forget to remove your palette.</p>
<p><a href="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-6.png"><img class="alignnone size-full wp-image-19" title="Step 7" src="http://www.rapapaing.com/blog/wp-content/uploads/2011/02/clouds-6.png" alt="" width="384" height="288" /></a></p>
<h4>Finished!</h4>
<p>There, now you have a bunch of pixels that look like a cloud. Now make lots of them and now you have your sky!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rapapaing.com/blog/?feed=rss2&#038;p=12</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

