Skip to content

Commit

Permalink
first cut, mostly non-functional.
Browse files Browse the repository at this point in the history
  • Loading branch information
shortishly committed Mar 12, 2012
0 parents commit 747bb77
Show file tree
Hide file tree
Showing 15 changed files with 435 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*~
*.beam
deps/*
erl_crash.dump
*.plt
.eunit
7 changes: 7 additions & 0 deletions Emakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
% -*- mode: erlang -*-
{["src/*"],
[{i, "include"},
{outdir, "ebin"},
% native,
debug_info]
}.
37 changes: 37 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
REBAR = rebar
DIALYZER = dialyzer
RM = rm

.PHONY: all clean deps compile test ct build-plt dialyze update

all: clean compile ct

clean:
@$(REBAR) clean

squeaky: clean
@$(REBAR) delete-deps

deps:
@$(REBAR) get-deps

compile:
@$(REBAR) compile

test:
@$(REBAR) skip_deps=true eunit

ct:
@$(REBAR) ct skip_deps=true

update:
@$(REBAR) update-deps


build-plt:
@$(DIALYZER) --build_plt --output_plt .gm_dialyzer.plt \
--apps kernel stdlib sasl inets crypto public_key ssl

dialyze:
@$(DIALYZER) --src src --plt .gm_dialyzer.plt -Werror_handling \
-Wrace_conditions -Wunmatched_returns -Wunderspecs -Wno_behaviours
57 changes: 57 additions & 0 deletions SAMPLE
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
INFO REPORT <0.55.0> 2012-03-11 16:03:46
===============================================================================
ip {192,168,1,87}
source_port 5353
record
{dns_rec,{dns_header,0,true,'query',true,false,false,false,false,0},
[],
[{dns_rr,"_http._tcp.local",ptr,in,0,4500,
"Photosmart C5100 series [C6D2FD]._http._tcp.local",
undefined,[],false}],
[],
[{dns_rr,"HPC6D2FD.local",a,32769,0,120,
<<192,168,1,87>>,
undefined,[],false},
{dns_rr,"Photosmart C5100 series [C6D2FD]._http._tcp.local",
srv,32769,0,120,
{0,0,80,"HPC6D2FD.local"},
undefined,[],false},
{dns_rr,"Photosmart C5100 series [C6D2FD]._http._tcp.local",
txt,32769,0,4500,
[[]],
undefined,[],false}]}
header
[{id,0},
{qr,true},
{opcode,'query'},
{aa,true},
{tc,false},
{rd,false},
{ra,false},
{pr,false},
{rcode,0}]
record_type msg
questions []
answers
[[{domain,"_http._tcp.local"},
{type,ptr},
{class,in},
{ttl,4500},
{data,"Photosmart C5100 series [C6D2FD]._http._tcp.local"}]]
authorities []
resources
[[{domain,"HPC6D2FD.local"},
{type,a},
{class,32769},
{ttl,120},
{data,<<192,168,1,87>>}],
[{domain,"Photosmart C5100 series [C6D2FD]._http._tcp.local"},
{type,srv},
{class,32769},
{ttl,120},
{data,{0,0,80,"HPC6D2FD.local"}}],
[{domain,"Photosmart C5100 series [C6D2FD]._http._tcp.local"},
{type,txt},
{class,32769},
{ttl,4500},
{data,[[]]}]]
14 changes: 14 additions & 0 deletions dev.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
%% -*- mode: erlang -*-
[
{kernel, [
{error_logger, {file, "logs/kernel.log"}}
]},

{sasl, [
{sasl_error_logger, {file, "logs/sasl.log"}},
{error_logger_mf_dir,"logs"},
{error_logger_mf_maxbytes,10485760},
{error_logger_mf_maxfiles, 10},
{errlog_type, all}
]}
].
2 changes: 2 additions & 0 deletions ebin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.app
*.beam
4 changes: 4 additions & 0 deletions logs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[0-9]
1[0-9]
index
*.log
12 changes: 12 additions & 0 deletions src/zeroconf.app.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{application, zeroconf,
[
{description, ""},
{vsn, "1"},
{registered, []},
{applications, [
kernel,
stdlib
]},
{mod, { zeroconf_app, []}},
{env, []}
]}.
23 changes: 23 additions & 0 deletions src/zeroconf.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
-module(zeroconf).
-export([announce/0,
start/0,
name/0,
stop/0,
make/0]).


name() ->
?MODULE.

start() ->
application:start(?MODULE).

announce() ->
gen_server:call(name(), announce).

stop() ->
gen_server:call(name(), stop).

make() ->
make:all([load]).

2 changes: 2 additions & 0 deletions src/zeroconf.hrl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-define(PORT, 5353).
-define(ADDRESS, {224, 0, 0, 251}).
16 changes: 16 additions & 0 deletions src/zeroconf_app.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
-module(zeroconf_app).

-behaviour(application).

%% Application callbacks
-export([start/2, stop/1]).

%% ===================================================================
%% Application callbacks
%% ===================================================================

start(_StartType, _StartArgs) ->
zeroconf_sup:start_link().

stop(_State) ->
ok.
151 changes: 151 additions & 0 deletions src/zeroconf_dns_sd.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
-module(zeroconf_dns_sd).
-behaviour(gen_server).
-define(SERVER, ?MODULE).

%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------

-export([start_link/0]).

%% ------------------------------------------------------------------
%% gen_server Function Exports
%% ------------------------------------------------------------------

-export([init/1,
handle_call/3,
handle_cast/2,
handle_info/2,
terminate/2,
code_change/3]).

-export([advertise/0,
stop/0]).


-include("zeroconf.hrl").

%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------

start_link() ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).

advertise() ->
gen_server:call(?SERVER, advertise).

stop() ->
gen_server:call(?SERVER, stop).

%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------

-record(state, {socket}).

init(_) ->
{ok, Socket} = gen_udp:open(?PORT, [{reuseaddr, true},
{multicast_if, multicast_if()},
{ip, ?ADDRESS}]),
{ok, #state{socket = Socket}}.

multicast_if() ->
{ok, Interfaces} = inet:getifaddrs(),
multicast_if(Interfaces).

multicast_if([{_, H} | T]) ->
case is_running_multicast_interface(proplists:get_value(flags, H)) of
true ->
v4(proplists:get_all_values(addr, H));
false ->
multicast_if(T)
end.

v4([{_, _, _, _} = V4 | _]) ->
V4;
v4([_ | T]) ->
v4(T).

is_running_multicast_interface(Flags) ->
lists:member(up, Flags) andalso
lists:member(broadcast, Flags) andalso
lists:member(running, Flags) andalso
lists:member(multicast, Flags).

handle_call(advertise, _, State) ->
{ok, Names} = net_adm:names(),
{ok, Hostname} = inet:gethostname(),
{reply, announce(Names, Hostname, State), State};

handle_call(stop, _, State) ->
{stop, normal, State}.

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(_Info, State) ->
{noreply, State}.

terminate(_, #state{socket = Socket}) ->
gen_udp:close(Socket).

code_change(_OldVsn, State, _Extra) ->
{ok, State}.

%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------


announce(Names, Hostname, #state{socket = Socket}) ->
Domain = "_erlang._udp.local",
Header = inet_dns:make_header([{id,0},
{qr,true},
{opcode,'query'},
{aa,true},
{tc,false},
{rd,false},
{ra,false},
{pr,false},
{rcode,0}]),
Answer = inet_dns:make_rr([{type, ptr},
{domain, Domain},
{class, in},
{ttl, 4500},
{data, Hostname ++ "._erlang._udp.local"}
]),
Message = message(Header,
[Answer],
services(Names, Hostname, 120) ++ texts(Names, Hostname, 120)),
error_logger:info_report([{socket, Socket},
{address, ?ADDRESS},
{port, ?PORT},
{message, Message}]),
gen_udp:send(Socket,
?ADDRESS,
?PORT,
inet_dns:encode(Message)).



message(Header, Answers, Resources) ->
inet_dns:make_msg([{header, Header},
{anlist, Answers},
{arlist, Resources}]).

services(Names, Hostname, TTL) ->
[inet_dns:make_rr([{domain, "_erlang._udp.local"},
{type, srv},
{class, in},
{ttl, TTL},
{data, {0, 0, Port, Hostname ++ ".local"}}]) || {_, Port} <- Names].

texts(Names, _Hostname, TTL) ->
[inet_dns:make_rr([{domain, "_erlang._udp.local"},
{type, txt},
{class, in},
{ttl, TTL},
{data, [[]]}]) || {_, _} <- Names].


Loading

0 comments on commit 747bb77

Please sign in to comment.