20
20
%% Primitive inet_drv interface
23
22
-export([open/1, open/2, fdopen/2, fdopen/3, close/1]).
24
23
-export([bind/3, listen/1, listen/2]).
25
24
-export([connect/3, connect/4, async_connect/4]).
242
240
accept0(L, Time) when port(L), integer(Time) ->
243
241
case async_accept(L, Time) of
246
{inet_async, S, Ref, Status} ->
248
ok -> accept_opts(L, S);
249
Error -> close(S), Error
244
{inet_async, L, Ref, {ok,S}} ->
246
{inet_async, L, Ref, Error} ->
255
252
%% setup options from listen socket on the connected socket
256
253
accept_opts(L, S) ->
257
case getopts(L, [active, nodelay, keepalive, delay_send]) of
254
case getopts(L, [active, nodelay, keepalive, delay_send, priority, tos]) of
259
256
case setopts(S, Opts) of
267
264
async_accept(L, Time) ->
274
case ctl_cmd(S,?TCP_REQ_ACCEPT,
275
[enc_time(Time),?int16(IX)]) of
276
{ok, [R1,R0]} -> {ok, S, ?u16(R1,R0)};
277
Error -> close(S), Error
265
case ctl_cmd(L,?TCP_REQ_ACCEPT, [enc_time(Time)]) of
266
{ok, [R1,R0]} -> {ok, ?u16(R1,R0)};
290
274
%% set listen mode on socket
292
276
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293
278
listen(S) -> listen(S, ?LISTEN_BACKLOG).
295
280
listen(S, BackLog) when port(S), integer(BackLog) ->
313
298
{inet_reply, S, Status} -> Status
315
{'EXIT', _Reason} -> {error, einval}
318
304
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
324
310
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
326
312
sendto(S,IP,Port,Data) when port(S), Port >= 0, Port =< 65535 ->
327
case catch erlang:port_command(S, [?int16(Port), ip_to_bytes(IP),Data]) of
313
case catch erlang:port_command(S, [?int16(Port), ip_to_bytes(IP), Data]) of
330
316
{inet_reply, S, Reply} -> Reply
332
{'EXIT', _Reason} -> {error, einval}
335
322
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341
328
%% N read N bytes
343
330
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344
332
recv(S, Length) -> recv0(S, Length, -1).
346
334
recv(S, Length, infinity) -> recv0(S, Length,-1);
363
351
case ctl_cmd(S, ?TCP_REQ_RECV, [enc_time(Time), ?int32(Length)]) of
364
352
{ok,[R1,R0]} -> {ok, ?u16(R1,R0)};
369
356
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618
604
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620
606
getindex(S) when port(S) ->
621
case ctl_cmd(S, ?INET_REQ_GETIX, []) of
622
{ok, [I3,I2,I1,I0]} -> {ok, ?u32(I3,I2,I1,I0)};
626
610
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674
658
gethostname(S) when port(S) ->
675
659
ctl_cmd(S, ?INET_REQ_GETHOSTNAME, []).
678
661
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680
663
%% GETSERVBYNAME(insock(),Name,Proto) -> {ok,Port} | {error, Reason}
771
753
{'EXIT', Reason} -> {error, Reason}
775
756
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777
758
%% INTERNAL FUNCTIONS
779
760
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781
is_sockopt_val(Opt,Val) ->
762
is_sockopt_val(Opt, Val) ->
782
763
case type_opt(Opt) of
783
764
undefined -> false;
784
765
Type -> type_value(Type,Val)
786
is_sockopt_val(_,_) ->
790
769
%% Socket options processing
796
775
enc_opt(broadcast) -> ?INET_OPT_BROADCAST;
797
776
enc_opt(sndbuf) -> ?INET_OPT_SNDBUF;
798
777
enc_opt(recbuf) -> ?INET_OPT_RCVBUF;
778
enc_opt(priority) -> ?INET_OPT_PRIORITY;
779
enc_opt(tos) -> ?INET_OPT_TOS;
799
780
enc_opt(nodelay) -> ?TCP_OPT_NODELAY;
800
781
enc_opt(multicast_if) -> ?UDP_OPT_MULTICAST_IF;
801
782
enc_opt(multicast_ttl) -> ?UDP_OPT_MULTICAST_TTL;
814
795
enc_opt(bit8) -> ?INET_LOPT_BIT8;
815
796
enc_opt(send_timeout) -> ?INET_LOPT_TCP_SEND_TIMEOUT;
816
797
enc_opt(delay_send) -> ?INET_LOPT_TCP_DELAY_SEND;
798
enc_opt(packet_size) -> ?INET_LOPT_PACKET_SIZE;
799
enc_opt(read_packets) -> ?INET_LOPT_UDP_READ_PACKETS;
800
enc_opt(O) when is_atom(O) -> -1.
819
802
dec_opt(?INET_OPT_REUSEADDR) -> reuseaddr;
820
803
dec_opt(?INET_OPT_KEEPALIVE) -> keepalive;
823
806
dec_opt(?INET_OPT_BROADCAST) -> broadcast;
824
807
dec_opt(?INET_OPT_SNDBUF) -> sndbuf;
825
808
dec_opt(?INET_OPT_RCVBUF) -> recbuf;
809
dec_opt(?INET_OPT_PRIORITY) -> priority;
810
dec_opt(?INET_OPT_TOS) -> tos;
826
811
dec_opt(?TCP_OPT_NODELAY) -> nodelay;
827
812
dec_opt(?UDP_OPT_MULTICAST_IF) -> multicast_if;
828
813
dec_opt(?UDP_OPT_MULTICAST_TTL) -> multicast_ttl;
840
825
dec_opt(?INET_LOPT_TCP_LOWTRMRK) -> low_watermark;
841
826
dec_opt(?INET_LOPT_BIT8) -> bit8;
842
827
dec_opt(?INET_LOPT_TCP_SEND_TIMEOUT) -> send_timeout;
843
dec_opt(?INET_LOPT_TCP_DELAY_SEND) -> delay_send;
844
dec_opt(_) -> undefined.
828
dec_opt(?INET_LOPT_TCP_DELAY_SEND) -> delay_send;
829
dec_opt(?INET_LOPT_PACKET_SIZE) -> packet_size;
830
dec_opt(?INET_LOPT_UDP_READ_PACKETS) -> read_packets;
831
dec_opt(I) when is_integer(I) -> undefined.
846
833
type_opt(reuseaddr) -> bool;
847
834
type_opt(keepalive) -> bool;
860
849
%% driver options
861
850
type_opt(header) -> uint;
862
851
type_opt(buffer) -> int;
864
853
{enum, [{false, 0}, {true, 1}, {once, 2}]};
866
855
{enum, [{0, ?TCP_PB_RAW},
882
871
type_opt(deliver) ->
883
872
{enum, [{port, ?INET_DELIVER_PORT},
884
873
{term, ?INET_DELIVER_TERM}]};
886
type_opt(exit_on_close) -> bool;
887
type_opt(low_watermark) -> int;
888
type_opt(high_watermark) -> int;
874
type_opt(exit_on_close) -> bool;
875
type_opt(low_watermark) -> int;
876
type_opt(high_watermark) -> int;
889
877
type_opt(bit8) ->
890
878
{enum, [{clear, ?INET_BIT8_CLEAR},
891
879
{set, ?INET_BIT8_SET},
892
880
{on, ?INET_BIT8_ON},
893
881
{off, ?INET_BIT8_OFF}]};
894
type_opt(send_timeout) -> time;
895
type_opt(delay_send) -> bool;
896
type_opt(_) -> undefined.
882
type_opt(send_timeout) -> time;
883
type_opt(delay_send) -> bool;
884
type_opt(packet_size) -> uint;
885
type_opt(read_packets) -> uint;
886
type_opt(O) when is_atom(O) -> undefined.
900
889
type_value(bool, true) -> true;
904
893
type_value(time, infinity) -> true;
905
894
type_value(time, X) when integer(X), X>=0 -> true;
906
895
type_value(ip,{A,B,C,D}) when ?ip(A,B,C,D) -> true;
907
type_value(ether,[_X1,_X2,_X3,_X4,_X5,_X6]) -> true;
896
type_value(ether,[_X1,_X2,_X3,_X4,_X5,_X6]) -> true;
908
897
type_value({X,Y},{XV,YV}) -> type_value(X,XV) and type_value(Y,YV);
909
898
type_value({enum,List},Enum) ->
910
899
case enum_val(Enum, List) of
925
914
enc_value(uint, Val) -> ?int32(Val);
926
915
enc_value(time, infinity) -> ?int32(-1);
927
916
enc_value(time, Val) -> ?int32(Val);
928
enc_value(ip,{A,B,C,D}) -> [A,B,C,D];
929
enc_value(ip,any) -> [0,0,0,0];
930
enc_value(ip,loopback) -> [127,0,0,1];
917
enc_value(ip,{A,B,C,D}) -> [A,B,C,D];
918
enc_value(ip,any) -> [0,0,0,0];
919
enc_value(ip,loopback) -> [127,0,0,1];
931
920
enc_value(ether,[X1,X2,X3,X4,X5,X6]) -> [X1,X2,X3,X4,X5,X6];
932
921
enc_value({enum,List},Enum) ->
933
922
{value,Val} = enum_val(Enum, List),
984
973
enum_vals([], _) -> [].
986
975
enum_names(Val, [{Enum,BitVal} |List]) ->
987
if Val band BitVal == BitVal ->
976
if Val band BitVal =:= BitVal ->
988
977
[Enum | enum_names(Val, List)];
990
979
enum_names(Val, List)
1000
989
enum_name(_, []) -> false.
1002
991
%% encode opt/val REVERSED since options are stored in reverse order
1003
%% i.e the recent options first (we must process old -> new)
992
%% i.e. the recent options first (we must process old -> new)
1004
993
encode_opt_val(Opts) -> enc_opt_val(Opts, []).
1006
995
enc_opt_val([{Opt,Val} | Opts], Acc) ->
1065
1054
{no_pointtopoint, ?INET_IFF_NPOINTTOPOINT},
1066
1055
{running, ?INET_IFF_RUNNING},
1067
1056
{multicast, ?INET_IFF_MULTICAST}]};
1068
type_ifopt(hwaddr) -> ether;
1069
type_ifopt(_) -> undefined.
1057
type_ifopt(hwaddr) -> ether;
1058
type_ifopt(Opt) when is_atom(Opt) -> undefined.
1071
1060
enc_ifopt(addr) -> ?INET_IFOPT_ADDR;
1072
1061
enc_ifopt(broadaddr) -> ?INET_IFOPT_BROADADDR;
1075
1064
enc_ifopt(netmask) -> ?INET_IFOPT_NETMASK;
1076
1065
enc_ifopt(flags) -> ?INET_IFOPT_FLAGS;
1077
1066
enc_ifopt(hwaddr) -> ?INET_IFOPT_HWADDR;
1067
enc_ifopt(Opt) when is_atom(Opt) -> -1.
1080
1069
dec_ifopt(?INET_IFOPT_ADDR) -> addr;
1081
1070
dec_ifopt(?INET_IFOPT_BROADADDR) -> broadaddr;
1084
1073
dec_ifopt(?INET_IFOPT_NETMASK) -> netmask;
1085
1074
dec_ifopt(?INET_IFOPT_FLAGS) -> flags;
1086
1075
dec_ifopt(?INET_IFOPT_HWADDR) -> hwaddr;
1087
dec_ifopt(_) -> undefined.
1076
dec_ifopt(I) when is_integer(I) -> undefined.
1089
1078
%% decode if options returns a reversed list
1090
1079
decode_ifopts([B | Buf], Acc) ->
1218
1207
enum_names(Flags,
1220
1209
{busy, ?INET_F_BUSY},
1221
{listening, ?INET_F_LST},
1210
%% {listening, ?INET_F_LST}, NOT USED ANY MORE
1222
1211
{accepting, ?INET_F_ACC},
1223
1212
{connecting, ?INET_F_CON},
1224
1213
{listen, ?INET_F_LISTEN},
1266
1255
rev([C|L],Acc) -> rev(L,[C|Acc]);
1267
1256
rev([],Acc) -> Acc.
1269
ip_to_bytes(IP) when size(IP) == 4 -> ip4_to_bytes(IP);
1270
ip_to_bytes(IP) when size(IP) == 8 -> ip6_to_bytes(IP).
1258
ip_to_bytes(IP) when size(IP) =:= 4 -> ip4_to_bytes(IP);
1259
ip_to_bytes(IP) when size(IP) =:= 8 -> ip6_to_bytes(IP).
1273
1261
ip4_to_bytes({A,B,C,D}) ->
1274
1262
[A band 16#ff, B band 16#ff, C band 16#ff, D band 16#ff].
1290
1278
%% Control command
1291
1279
ctl_cmd(Port, Cmd, Args) ->
1292
case catch port_control(Port, Cmd, Args) of
1293
[?INET_REP_OK | Reply] -> {ok, Reply};
1280
case catch erlang:port_control(Port, Cmd, Args) of
1281
[?INET_REP_OK | Reply] -> {ok, Reply};
1294
1282
[?INET_REP_ERROR| Err] -> {error, list_to_atom(Err)};
1295
1283
{'EXIT', _} -> {error, einval};
1296
1284
_ -> {error, internal}