Giter VIP home page Giter VIP logo

ddhcpd's People

Contributors

benbe avatar christf avatar moritzfago avatar rubo77 avatar sargon avatar tobleminer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ddhcpd's Issues

Suggestion: get rid of ddhcpdctl and use uc instead saving space in the image

We could replace ddhcpctl with uc from https://github.com/christf/uc.git saving some space in the image and further modularizing our builds.
uc is more generic and also used by prefixd and can be used for diagnostics together with l3roamd.

echo get_blocks | uc /tmp/ddhcpd_ctl

ddhcpd requires a different input format at the moment, this change would have implications on the design of the socket. In the code is a TODO for it to be redesigned. This could be an option.

dhcp_options - broadcast address

There is a bug in the shifting logic in dhcp_options.
When not specifying -o 28:4:a.b.c.d an invalid broadcast address is distributed.
For -N 10.126.0.0/16 the broadcast address 0.126.255.255 is served.

Move initial data structures to stack

https://github.com/sargon/ddhcpd/blob/master/main.c#L130 allocates the config on the heap. As far as I can see the stack frame of the main method should be valid throughout the whole lifetime of the program. I think we could just put it on the stack, couldn't we? That way we won't have to deal with allocation failues.

The same goes for the event buffer at https://github.com/sargon/ddhcpd/blob/master/main.c#L363

also for the packet buffer at https://github.com/sargon/ddhcpd/blob/master/main.c#L340

and even the packet buffer in https://github.com/sargon/ddhcpd/blob/master/ddhcpctl.c#L28

ddhcpd does not notice when mesh interface is removed/recreated

In l3 networks the mesh interface for ddhcpd is the mmfd interface. Over the run-time of the node, this interface might be destroyed and re-created. At that time ddhcpd does not update the scope-id and attempts to re-use the old scope-id from that interface that already has been destroyed.

This results in block claims not happening any more and in
Mon Jan 6 09:22:52 2020 daemon.err ddhcpd[3128]: ERROR: send_packet_mcast(...): Failed (13): Permission denied

at the time when this log message was captured, there was no interface with id 13. The proper interface would have been
23: mmfd0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1280 qdisc fq_codel state UNKNOWN group default qlen 500

Allow setting loglevel via socket or command line switch

setting loglevel via compile-option is inconvenient as it forces the decision on the person building the firmware whether everyone using the resulting images will be a developer. At the same time it is hampering analysis in images that were not built with verbose debug log in case a ddhcpd issue arises.

Being able to adjust the loglevel would help.

one client getting assigned multiple ipv4 addresses on consecutive runs of dhclient

the client in my case ends up with many ipv4 addresses in the same subnet.
Two of the currently three assigned addresses are within the same block, the third is in another block.

root@60489-luna:/tmp# ddhcpdctl -b
block size/number	4/16384 
      tentative timeout	15
      timeout	60
      refresh factor	4
      spare	1
      network: 10.126.0.0/16 
node id	0000000000000000
ddhcp blocks
index	state	owner			claim	leases	timeout
4275	4	0000000000000000	3	0/4	48
4539	2	0000000000000000	0	-	12
5403	4	0000000000000000	3	0/2	48
7024	2	0000000000000000	0	-	9
14891	4	0000000000000000	3	0/4	48

Fork a hook process, instead of forking every time.

We could fork a process early and then pass events by a unnamed socket.
This would solve the issue with multiple hook script instances, forking
on every event and prevent and resources over consumption by an event
spike.

default gateway not delivered by ddhcp

ddhcpd is started with
/usr/sbin/ddhcpd -D -s 1 -b 2 -c local-node -i mmfd0 -N 10.139.0.0 17 -o 51 4 0 0 1 44 -o 3 4 10 139 0 1 -o 6 4 10 139 0 1

but default gateway are not assigned to clients. According to tcpdump they are not provided by ddhcpd. Am I missing something?

Add mechanism for compile-time feature support

As some features in the pipeline may not be of much use for minimalistic clients it would be advisable to have a central point to configure such features (e.g. having a features.h, that is possibly auto-generated in the Makefile if it doesn't exist). The format could be as simple as a list of defines which only carry boolean values.

Verbosity level affect the program functionality on Raspberry Pi

I have run DDHCPD on Raspberry Pi successfuly. However, when I have specified verbosity twice: sudo ./ddhcpd -c eth0 -i eth0 -v -v, I got segmentation error after about 10-15 seconds. The output looks like this:

ubuntu@ubuntu:~/ddhcpd$ sudo ./ddhcpd -c eth0 -i eth0 -v -v
INFO: CONFIG: network=10.0.0.0/24
INFO: CONFIG: block_size=32
INFO: CONFIG: #blocks=8
INFO: CONFIG: #spare_leases=2
INFO: CONFIG: timeout=60
INFO: CONFIG: refresh_factor=4
INFO: CONFIG: tentative_timeout=15
INFO: CONFIG: client_interface=eth0
INFO: CONFIG: group_interface=eth0
DEBUG: ddhcp_block_init(config)
DEBUG: find_in_option_store(store, code:1)
DEBUG: set_in_option_store(store, code:1, len4)
DEBUG: find_in_option_store(store, code:1)
DEBUG: set_in_option_store(...): inserting option
DEBUG: find_in_option_store(store, code:2)
DEBUG: set_in_option_store(store, code:2, len4)
DEBUG: find_in_option_store(store, code:2)
DEBUG: set_in_option_store(...): inserting option
DEBUG: find_in_option_store(store, code:28)
DEBUG: set_in_option_store(store, code:28, len4)
DEBUG: find_in_option_store(store, code:28)
DEBUG: set_in_option_store(...): inserting option
DEBUG: find_in_option_store(store, code:51)
DEBUG: set_in_option_store(store, code:51, len4)
DEBUG: find_in_option_store(store, code:51)
DEBUG: set_in_option_store(...): inserting option
DEBUG: find_in_option_store(store, code:54)
DEBUG: set_in_option_store(store, code:54, len4)
DEBUG: find_in_option_store(store, code:54)
DEBUG: set_in_option_store(...): inserting option
DEBUG: epoll_add_fd(3,-2147483647)
DEBUG: epoll_add_fd(3,-2147483647)
DEBUG: epoll_add_fd(3,-2147483647)
DEBUG: epoll_add_fd(3,-2147483647)
DEBUG: netlink_init(config)
DEBUG: epoll_add_fd(3,-2147483647)
INFO: loop timeout: 7500 msecs
DEBUG: netlink_callback(...): callback triggered
DEBUG: netlink_callback(...): iface(3) up
DEBUG: ntoh_dhcp_packet(...): package len:296
DEBUG: BOOTP [ op 1, htype 1, hlen 6, hops 0, xid 1106945831, secs 128, flags 0, ciaddr 0.0.0.0, DEBUG: yiaddr 0.0.0.0, DEBUG: siaddr 0.0.0.0, DEBUG: giaddr 0.0.0.0, sname: , file:  ]
DEBUG: DHCP OPTION [ code 53, length 1, value 1 ]
DEBUG: DHCP OPTION [ code 61, length 19 ]
DEBUG: DHCP OPTION [ code 55, length 11, value 1 3 12 15 6 26 33 121 119 42 120 ]
DEBUG: DHCP OPTION [ code 57, length 2 ]
DEBUG: DHCP OPTION [ code 50, length 4 ]
DEBUG: DHCP OPTION [ code 12, length 6 ]
DEBUG: DHCP OPTION [ code 255, length 0 ]
DEBUG: dhcp_hdl_discover(socket:8, packet, config)
DEBUG: block_find_free_leases(config)
DEBUG: block_find_free_leases(...): No block found!
DEBUG: dhcp_hdl_discover(...): no block with free leases found
DEBUG: Segmentation fault

If I set up verbosity with only one flag, everything is working perfectly. Raspberry is running on ubuntu server 20.04 for raspberries.

dhcp_packaet.c: -Werror=implicit-fallthrough=

exit = 1;

echo '#define REVISION "3cbb8be3435996fdb33ad7b63e3ad10481e5603a"' > version.h
gcc -Wall -Wextra -pedantic -Werror -flto -fno-strict-aliasing -std=gnu11 -D_GNU_SOURCE -MD -MP -DNDEBUG   -c -o dhcp_packet.o dhcp_packet.c
dhcp_packet.c: In function ‘ntoh_dhcp_packet’:
dhcp_packet.c:207:12: error: this statement may fall through [-Werror=implicit-fallthrough=]
       exit = 1;
       ~~~~~^~~
dhcp_packet.c:209:5: note: here
     case DHCP_CODE_PAD:
     ^~~~
cc1: all warnings being treated as errors
make: *** [<builtin>: dhcp_packet.o] Error 1

RFC2132 compliance

We should check if we are fully compliant to RFC 2132 and if all necessary features mentioned in there are properly implemented.

add ubus calls

As you offer a CLI changing parameters on the run, it should be easy to add some UBUS functionality.

Is that a planned feature?

gluon build error

I built the current ffki-site nightly version, but the build with -j1 V=s stops with this error

make[4]: Entering directory '/media/ruben/linuxbackup/gluon/packages/sargon/ddhcpd'
CFLAGS="-Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -DLOG_LEVEL=20  -mips16 -minterlink-mips16 -iremap/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28:ddhcpd-2018-06-28 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro  -I/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/usr/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/usr/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include/fortify -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include " CXXFLAGS="-Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -DLOG_LEVEL=20  -mips16 -minterlink-mips16 -iremap/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28:ddhcpd-2018-06-28 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro  -I/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/usr/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/usr/include -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include/fortify -I/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include " LDFLAGS="-L/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/usr/lib -L/media/ruben/linuxbackup/gluon/lede/staging_dir/target-mips_24kc_musl-1.1.16/lib -L/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/usr/lib -L/media/ruben/linuxbackup/gluon/lede/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/lib -znow -zrelro " make -C /media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/. AR="mips-openwrt-linux-musl-gcc-ar" AS="mips-openwrt-linux-musl-gcc -c -Os -pipe -mno-branch-likely -mips32r2 -mtune=24kc -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -DLOG_LEVEL=20 -iremap/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28:ddhcpd-2018-06-28 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro" LD=mips-openwrt-linux-musl-ld NM="mips-openwrt-linux-musl-gcc-nm" CC="mips-openwrt-linux-musl-gcc" GCC="mips-openwrt-linux-musl-gcc" CXX="mips-openwrt-linux-musl-g++" RANLIB="mips-openwrt-linux-musl-gcc-ranlib" STRIP=mips-openwrt-linux-musl-strip OBJCOPY=mips-openwrt-linux-musl-objcopy OBJDUMP=mips-openwrt-linux-musl-objdump SIZE=mips-openwrt-linux-musl-size CROSS="mips-openwrt-linux-musl-" ARCH="mips" DESTDIR="/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/ipkg-install"  install;
make[5]: Entering directory '/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28'
install -D -p    -m  755 ddhcpd /media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/ipkg-install/usr/sbin/ddhcpd
install: cannot stat 'ddhcpd': No such file or directory
Makefile:59: recipe for target 'install' failed
make[5]: *** [install] Error 1
make[5]: Leaving directory '/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28'
Makefile:36: recipe for target '/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/.built' failed
make[4]: *** [/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/.built] Error 2
make[4]: Leaving directory '/media/ruben/linuxbackup/gluon/packages/sargon/ddhcpd'
package/Makefile:105: recipe for target 'package/feeds/packages_sargon/ddhcpd/compile' failed

indeed the folder

/media/ruben/linuxbackup/gluon/lede/build_dir/target-mips_24kc_musl-1.1.16/ddhcpd-2018-06-28/ipkg-install/usr/sbin/

is empty

Merge package to upstream

I found a ddhcpd package but it's specialized for Gluon. As other community mesh projects or use cases could profit of this work, can we create a generic package version to merge in upstream?

The Gluon specific package could simply add ddhcpd as a dependence.

IPv6 support

LibreMesh uses dnsmasq-dhcpv6 and lease sharing via alfred to allow IPv6 roaming. Would it be possible to integrate IPV6 support here as well so it'd be a full DHCP replacement?

overwriting nameserver on client-side

when used together with uradvd on server and networkmanager on the client side, the small timeouts lead to the resolv.conf being overwritten frequently and ipv6 nameserver being blocked.

This obviously is a client-side issue. Maybe add/link some docs how to overcome this and both nameservers (ipv6 and ipv4) remain active?

Support for DHCPINFORM

As of RFC2131 we should support DHCPINFORM message type, to be honest I don't expect many clients to be able to use this feature, but we should support it.

netmask and broadcast address

In a l2 mesh we can globally set the netmask and broadcast addresses. ddhcp currently allows that relying on the appropriate dhcp options as specified by -o.

In l3 networks the netmask and broadcast address should be different for every node in the net.
To make matters worse, these values change when new blocks are reserved by ddhcpd for this given node.

Without subnet mask, dhclient (default on many linux distributions) will not accept default gateway and ipv4 will be broken.

I am not sure how best deal with that. I see two options:

  • enhance hook events to allow calling hooks when blocks are reserved and released. Then this hook could use the socket to re-configure the dhcp options of ddhcpd in-flight.
  • auto-adjust the netmask/broadcast address when not hard-coded via CLI. Since those dhcp-options are standard for every installation, they should always be delivered. If not specified, use a sane default.

Reuse used blocks first

It seems like, we are leasing from newer blocks instead of reusing already used blocks.

block size/number	4/256 
node id	00163EA4A1210000
ddhcp blocks
index	state	owner			claim	leases	timeout
144	4	00163EA4A1210000	3	0/1	15
225	4	00163EA4A1210000	3	0/1	15

In the leases field the first value are "reserved" addresses by a in progress dhcp discovery event and
the second value are the leased addresses.

record statistics

We should record some network statistics to improve the number of messages needed.
Numbers I would be interested are:

  • How may packets of which type do we send out.
  • How much traffic do we produce.

Furthermore we could extend the ctl binary to get and reset those counters, so we are able to
transfer them to some statistics service.

hooks: add hostname

currently the hooks only offer address and mac, would it be possible to add the clients hostname as an arg as well?

crash

on gluon I was able to see:
[41544.407792]
[41544.407792] do_page_fault(): sending SIGSEGV to ddhcpd for invalid write access to 00d5524c
[41544.414761] epc = 77cdaf5c in libc.so[77cb2000+92000]
[41544.419729] ra = 77cdaf34 in libc.so[77cb2000+92000]
[41544.424756]

attached is the core file (rename from png)
ddhcpd 1529728411 3028 11 core

unfortunately I cannot see much with gdb:

christof@build:/var/lib/jenkins/workspace/babel-dev/wspace/lede$ ./build_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/gdb-8.0.1/gdb/gdb ./staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/ddhcpd /tmp/ddhcpd.1529728411.3028.11.core.png
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=mips-openwrt-linux-musl".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/ddhcpd...done.
[New LWP 3028]

warning: Can't read pathname for load map: Unbekannter Fehler -1.

warning: Could not load shared library symbols for 2 libraries, e.g. /lib/libgcc_s.so.1.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `/usr/sbin/ddhcpd -D -s 1 -b 2 -c local-node -i br-client -N 10.126.0.0 16 -H /e'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x77766f5c in ?? ()
(gdb) bt
#0  0x77766f5c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) info sharedlibrary
warning: Can't read pathname for load map: Unbekannter Fehler -1.
From        To          Syms Read   Shared Object Library
                        No          /lib/libgcc_s.so.1
                        No          /lib/ld-musl-mips-sf.so.1
(gdb) bt
#0  0x77766f5c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

I can see that the command line is cut off. I am starting ddhcpd like this:

 4508 root      2204 S    /usr/sbin/ddhcpd -D -s 1 -b 2 -c local-node -i br-client -N 10.126.0.0 16 -H /etc/ddhcpd.hook -o 51 4 0 0 1 44 -o 3 4 10 126 0 1 -o 6 4 10 126 0 1 -o 54 4 10 126 0 1 -o 1 4 255 255 0 0 -i mmfd0

this is the log up to the crash.

Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: network=10.126.0.0/16
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: block_size=4
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: #blocks=16384
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: #spare_blocks=1
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: timeout=60
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: refresh_factor=4
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: tentative_timeout=15
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: client_interface=local-node
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: CONFIG: group_interface=mmfd0
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: ddhcp_block_init(config)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 1)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store(...) -> 1
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 2)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: set_in_option_store( store, code/len: 2/4)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 2)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: set_in_option_store(...) -> append option
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 28)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store(...) -> 28
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 51)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store(...) -> 51
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store( store, code: 54)
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: DEBUG: find_in_option_store(...) -> 54
Sat Jun 23 16:21:48 2018 daemon.err ddhcpd[30989]: INFO: loop timeout: 7500 msecs

More visible license information

The license is only visible in the Debian directory. Please add it to the Readme and to the Github project information.
This would be very helpful for those who have to check licenses in order to incorporate third party software.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.